[This lab](https://portswigger.net/web-security/websockets/lab-manipulating-handshake-to-exploit-vulnerabilities) combines two attack surfaces: **WebSocket message manipulation** and **WebSocket handshake tampering**. The goal is to bypass a flawed but aggressive XSS filter in the live chat system, which is also protected by an IP-based blocking mechanism.
Our mission: deliver an obfuscated XSS payload to the support agent via WebSocket, even after being banned by the IP filter.
---
##### Understanding the Scenario
The application’s live chat is powered by WebSockets. Each message is sent as a WebSocket frame, and the support agent receives and renders them in real time. However:
* Messages are aggressively filtered to block obvious XSS.
* Attempting a blocked payload triggers **IP-based banning**, enforced at the WebSocket handshake stage.
* The ban is based on the IP from the handshake request — which we can spoof using HTTP headers.
---
##### Reconnaissance
1. **Send a normal chat message** and observe it in **Burp → Proxy → WebSockets** history.
2. **Send a basic XSS payload** via WebSocket frame:
```html
<img src=1 onerror='alert(1)'>
```
Result:
* The message is blocked.
* The WebSocket connection is terminated.
* Attempting to reconnect fails — IP banned.
---
##### The IP Ban Mechanism
After being blocked, the WebSocket handshake fails. The handshake request is an HTTP upgrade request like:
```
GET /chat HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: ...
Origin: https://YOUR-LAB-ID.web-security-academy.net
```
The ban relies on detecting your real IP — likely via the TCP connection or headers.
If the server uses the `X-Forwarded-For` header for IP detection, we can spoof our address.
![[CleanShot 2025-08-13 at
[email protected]]]
---
##### Spoofing the IP in the Handshake
To bypass the ban:
1. In Burp, **intercept the WebSocket handshake** request.
2. Add the spoofing header:
```
X-Forwarded-For: 1.1.1.1
```
3. Forward the request — connection is re-established.
To do that easily add match/replace rule:
![[CleanShot 2025-08-13 at
[email protected]]]
---
##### Crafting the Bypass Payload
The lab’s XSS filter is strict but flawed. Using attribute name obfuscation bypasses it.
Instead of `onerror`, we can use **mixed-case event handlers** and **template literal backticks**:
```html
<img src=1 oNeRrOr=alert`1`>
```
This evades naive filters that:
* Match only lowercase `onerror`
* Block normal parentheses but not backticks
---
##### Exploitation Steps
1. Reconnect the WebSocket using the spoofed IP header.
2. Send the obfuscated payload via WebSocket Repeater:
```
{"message":"<img src=1 oNeRrOr=alert`1`>"}
```
3. The support agent’s browser executes `alert(1)` — lab solved.
![[CleanShot 2025-08-13 at 23.10.18@2x 1.png]]