Vulnerabilities
WebSockets vs CORS for Browser APIs
June 15, 2026
WebSockets vs CORS for browser APIs is two different browser gates. CORS decides whether fetch/XHR may read a cross-origin HTTP response. A WebSocket starts as HTTP Upgrade; after the handshake, frames are not CORS-checked. Access-Control-Allow-Origin on the REST API does not protect wss://. The server must verify Origin (and cookies or tokens) on the upgrade. Reflecting any Origin or skipping the check is the miss. RoastMyOpsec app mode sends a bounded untrusted Origin on HTTP and reads ACAO. It does not open WebSockets, does not send upgrade frames, and does not score missing Origin checks on wss.
The practical difference
fetch() to https://api.example/data is CORS. new WebSocket('wss://api.example/ws') is a handshake the page's origin is sent on. Same-site cookies may attach depending on SameSite. JSONP is a third gate — script tags — already retired in the JSONP vs CORS guide.
SameSite=None cookies on a WebSocket cookie-auth API are an embed decision. Prefer tokens in the handshake your app already uses for HTTP, not a second cookie policy.
How to choose a gate
Public read-only WS: still allowlist Origin so random sites cannot open a socket on your users' behalf if the socket is cookie-authenticated. Anonymous market-data sockets can allow more origins but should not trust the client as a user. Authenticated sockets: Origin allowlist plus a session or ticket. Do not copy CORS * onto the upgrade.
| Channel | Browser gate | Server must | Takeaway |
|---|---|---|---|
| fetch / XHR | CORS | ACAO allowlist; still auth the user | See wildcard vs allowlist |
| WebSocket | No CORS on frames | Check Origin; authenticate upgrade | CORS headers do not apply |
| JSONP | Script tag | Retire it | See JSONP vs CORS |
| Same-origin WS | Same origin as the page | Still authenticate | Origin check is easy to get right |
What the roast can prove
HTTP ACAO and credentials behavior can surface. A 101 is not in the scan. Confirm Origin handling on your own upgrade path. Pair with CORS credentials vs wildcard if the socket uses cookies.
Common mistakes
The first mistake is tightening CORS and leaving the WebSocket Origin check as *.
The second mistake is cookie-auth sockets with SameSite=None for a widget you do not trust.
The third mistake is treating a roast ACAO pass as proof the socket is locked.
Free audit the URL you own
RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.
Free audit nowFAQ
- Does CORS protect WebSockets?
- No. Frames after upgrade are not CORS-gated. Check Origin and authenticate on the handshake.
- Should every site Origin-check WebSockets?
- If the socket is authenticated or user-specific, yes. Anonymous public streams still benefit from an allowlist.
- Does RoastMyOpsec open WebSockets?
- No. It does not send Upgrade or score wss Origin handling.
Sources
Related guides
Vulnerabilities
CORS Wildcard vs Allowlist for Public APIsVulnerabilities
CORS Credentials vs Wildcard OriginsVulnerabilities
postMessage vs CORS for Embedded Widgets