CSWH

Cross-Site WebSocket Hijacking (CSWH) is a vulnerability resulting from a CSRF attack on the WebSocket handshake. Unlike regular CSRF (send-only), CSWH provides attackers with write AND read access to data sent over the WebSocket connection because WebSockets are not as strictly bound by the Same-Origin Policy.


Code Review - Identifying the Vulnerability

Application Overview

Web application displays messages for logged-in users via WebSocket.

Database Queries (Secure)

def login(username, password):
    mydb = mysql.connector.connect(
        host="127.0.0.1",
        user="db",
        password="db-password",
        database="db"
    )
    mycursor = mydb.cursor(prepared=True)
    query = 'SELECT * FROM users WHERE username=%s AND password=%s'
    mycursor.execute(query, (username, password))
    return mycursor.fetchone()

def fetch_messages(username):
    mydb = mysql.connector.connect(...)
    mycursor = mydb.cursor(prepared=True)
    query = 'SELECT message FROM messages WHERE username=%s'
    mycursor.execute(query, (username,))
    return mycursor.fetchall()

Secure: Uses prepared statements β†’ No SQLi.

Login Endpoint

Sets session variables logged_in and user upon successful login.

WebSocket Endpoint (Vulnerable!)

Vulnerability Analysis

Issue
Description

Session cookie authentication

WebSocket uses session cookie for auth

No CSRF token

No additional CSRF protection

No Origin validation

Origin header not checked

Result: Vulnerable to CSRF on WebSocket handshake β†’ CSWH!


Confirming the Vulnerability

Normal WebSocket Handshake

Cross-Origin Test

Change Origin header to different domain:

Result: Server still responds with user's messages β†’ CSWH confirmed!


Exploitation

Attack Flow

Exploit Code

Host this on attacker-controlled site:

Exfiltrated Data (interact.sh)


Limitations

Important: For this exploit to work, the SameSite cookie flag must be set to None.

SameSite Value
CSWH Exploitable?

None

βœ… Yes

Lax (default in most browsers)

❌ No

Strict

❌ No

Most browsers apply default value of Lax if SameSite not set β†’ Attack requires deliberately insecure configuration.


Summary

Prevention

Method
Description

Validate Origin header

Reject WebSocket connections from unexpected origins

Use CSRF tokens

Require token in WebSocket handshake

SameSite=Strict/Lax

Prevents cross-site cookie sending

Additional authentication

Token-based auth for WebSocket, not just session cookie

Last updated