BIPI
BIPI

Web Sockets Pentesting: Origin Spoofing, CSWSH, and Message Tampering

Cybersecurity

WebSocket endpoints inherit none of CORS protections by default. We walk through Cross Site WebSocket Hijacking, message tampering, auth gaps, and the wsrepl and websocat workflows that real pentesters use.

By Arjun Raghavan, Security & Systems Lead, BIPI · December 8, 2023 · 9 min read

#websocket#cswsh#pentesting#auth#hijacking

Why WebSockets are different

The WebSocket handshake is HTTP, but CORS does not apply. The server sees the Origin header but is free to ignore it. Cookies are sent automatically. Result, if the server does not check Origin, any attacker page can open an authenticated socket on behalf of the victim.

Cross Site WebSocket Hijacking

Attacker page runs a WebSocket connection to wss://target/ws. Victim cookies attach. Attacker reads everything the server pushes and can send commands. This is CSWSH. It works because there is no preflight.

Detection workflow

  1. Open Burp, intercept the Upgrade request, note the URL and Origin header
  2. Try the same request with Origin: https://evil.example, if 101 returns, the server is open
  3. Use websocat -H 'Origin: https://evil.example' wss://target/ws to confirm interactively
  4. Use wsrepl for scripted message fuzzing once the connection is up

Message level bugs

Once inside the socket, treat every message as untrusted. We routinely find IDOR by changing a userId field in a chat message, command injection in admin frames that were assumed to be internal only, and JSON deserialization bugs in binary subprotocols.

  • Change recipient_id to harvest other users messages
  • Send admin scoped frames as a regular user, many apps only check role on connect
  • Inject SSTI or SQLi payloads in chat content fields
  • Replay captured frames against a different session to test idempotency

Subprotocol confusion

Servers that support multiple subprotocols sometimes pick the wrong parser if the Sec-WebSocket-Protocol header is crafted. STOMP over WS is a frequent offender, frames meant for one queue land on another.

Tooling stack

websocat for raw I O, wsrepl for an interactive REPL with history and scripting, Burp WebSocket history for replay, and a small Node script for fuzzing frame structures. ZAP has decent WS support too.

Detection on the defender side

  • Log every Upgrade with Origin, User-Agent, and authenticated user identity
  • Alert on Origin values not in the allow list
  • Rate limit messages per socket, not just per IP

Remediation

  1. Strict allowlist Origin check during handshake, reject otherwise
  2. Require a CSRF token bound to the session inside the first frame
  3. Use SameSite=Strict cookies or token in URL parameter so cross site contexts cannot ride the session
  4. Authorize every message, not just the handshake
$340k+
Bounty payouts for CSWSH in 2022 disclosures
31
Apps missing Origin checks in our last 50 tests
If your socket trusts the handshake forever, every message after is on the honor system.

Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.