CORS Doesn't Apply to WebSockets — and Your AI Agent Might Be Vulnerable
If you're building realtime AI agents with WebSockets and relying on cookies for authentication, the browser's Same-Origin Policy won't save you. Here's what you need to know about CWE-1385.
By Brian Cardinale
The conversation that started this
A colleague and I were reviewing a WebSocket-based AI agent endpoint. He pushed back on the idea that cross-site attacks were viable: "CORS is so strict these days—there's no way a random page can open a WebSocket to another domain and get authenticated access."
He was right about CORS. He was wrong about WebSockets.
We tested it. It took about two minutes to confirm that a page hosted on any domain can open a WebSocket connection to any other domain, and the browser will happily send along any cookies associated with that target. No preflight request. No CORS headers required. No browser-side blocking whatsoever.
For both of us, people who think about web security regularly, this was a genuine surprise. And if we didn't know, there are probably thousands of developers shipping vulnerable WebSocket endpoints right now who don't know either.
What's actually happening
The WebSocket API in browsers is explicitly excluded from the Same-Origin Policy. When JavaScript calls new WebSocket("wss://target.com/ws"), the browser:
- Sends an HTTP Upgrade request to the target
- Includes all cookies for that domain
- Sets the
Originheader to the page's origin (this cannot be spoofed from JavaScript) - Establishes the connection if the server returns HTTP 101
The browser does not block this based on origin. It does not require the server to send Access-Control-Allow-Origin headers. The connection just... works.
The only defense is the server inspecting the Origin header during the handshake and rejecting connections from unauthorized origins.
Why this matters for AI agents
WebSockets are a recommended transport for realtime AI interactions, such as voice agents, tool-call approval flows, multi-agent UIs, and anything requiring bidirectional streaming. OpenAI's Realtime API, Azure OpenAI GPT Realtime, and countless custom agents built with Socket.IO or raw WebSockets all use this pattern.
If these endpoints authenticate via session cookies without checking the Origin header, they are vulnerable to Cross-Site WebSocket Hijacking (CSWSH) which is catalogued by MITRE as CWE-1385.
An attacker can:
- Exfiltrate conversation history
- Inject prompts into an authenticated session
- Invoke connected tools on behalf of the user
- Maintain persistent, real-time access for as long as the victim has the attacker's page open
The fix is straightforward
- Validate the
Originheader on every WebSocket handshake against an explicit allowlist of your frontend domains - Don't rely on cookies alone — add a CSRF token, short-lived ticket, or bearer token to the handshake
- Reject
nullorigins — these come from sandboxed iframes and can be attacker-controlled - Use
wss://(TLS) exclusively in production
Most WebSocket libraries (Node ws, Go Gorilla, Python websockets) do not validate Origin by default. You must explicitly add it.
Full technical writeup and test harness
We published a detailed technical analysis with a ready-to-use test harness script on RedCaller:
Your AI Agent's WebSocket Isn't Protected by CORS (and That's a Problem)
References
- CWE-1385: Missing Origin Validation in WebSockets
- OWASP WebSocket Security Cheat Sheet
- OWASP Testing WebSockets (WSTG-CLNT-10)
- Christian Schneider — Cross-Site WebSocket Hijacking
Need help assessing the security of your AI agent infrastructure? SecureCoders offers penetration testing services for AI and voice agent systems.

