A blind spot in a lot of security reviews
Security review processes and tooling built around REST and HTTP APIs frequently have no equivalent coverage for WebSocket endpoints in the same application, even though a persistent connection can carry the same class of injection and authentication risks as any stateless request — plus a few risks that are specific to how persistent connections behave differently from request/response cycles.
Cross-site WebSocket hijacking: the risk unique to the handshake
Unlike typical cross-origin request protections built into modern browsers for standard HTTP requests, a WebSocket handshake can be initiated from any origin unless the server explicitly validates the Origin header itself. Without this check, a malicious website can open a WebSocket connection to your server using a visiting user's existing session cookies, effectively hijacking that authenticated connection from an entirely different site.
Why cookies alone aren't sufficient authentication
Because a WebSocket handshake request carries cookies automatically just like any HTTP request, relying on cookie-based session identification alone for the handshake provides no additional protection beyond what Origin validation already needs to cover — an explicit authentication token, checked at connection time, adds a distinct layer that doesn't depend solely on cookie presence.
The resource-exhaustion risks unique to persistent connections
- Message rate limiting. A single open WebSocket connection can send messages at a rate far exceeding what typical per-request HTTP rate limiting is designed to catch, since it's not bound by the overhead of establishing a new connection for each message.
- Concurrent connection limits. Without a cap on how many connections a single user or IP can hold open simultaneously, WebSockets present a straightforward resource-exhaustion vector distinct from typical HTTP request flooding.
- Message size limits. An unbounded maximum message size accepted over a socket is a memory-exhaustion risk that a REST API's typical body-size limits don't automatically extend to cover.
Why long-lived connections need periodic re-authorization
A WebSocket connection authenticated at the moment it was opened can remain open for hours or days, during which the user's underlying permissions might change or be revoked entirely — without periodic re-verification, the connection can retain access levels that no longer reflect the user's actual current authorization.
Treating socket messages like any other untrusted input
It's easy to mentally categorize WebSocket messages as internal or trusted simply because the connection was already authenticated at handshake time — but each individual message still represents user-controlled input that deserves the same validation and sanitization scrutiny as a REST request body, regardless of how the connection itself was established.
Testing it separately matters
Persistent connection behavior under load — connection accumulation, message backpressure, resource cleanup on disconnect — differs meaningfully from stateless request/response load testing, and a load test suite built entirely around REST endpoints typically doesn't exercise these WebSocket-specific failure modes at all.
Frequently Asked Questions
Unlike standard HTTP requests, a WebSocket handshake isn't automatically protected by browser cross-origin request restrictions, so a malicious website can open a WebSocket connection to your server using a visiting user's existing session cookies. Validating the Origin header on the server-side handshake explicitly rejects connections initiated from unauthorized origins, closing this gap.
WebSocket handshake requests carry cookies automatically, just like any HTTP request, so cookie presence alone doesn't provide protection beyond what Origin validation already needs to address. An explicit authentication token checked at connection time adds a distinct layer of verification that doesn't depend solely on cookies being present.
A single open WebSocket connection can send messages far faster than typical per-request HTTP rate limiting is designed to catch, since it isn't bound by the overhead of establishing a new connection for each message the way repeated HTTP requests are.
A connection authenticated at the moment it opened can remain active for hours or days, during which the user's actual permissions might be changed or revoked. Without periodic re-verification, the connection can continue operating with access levels that no longer reflect the user's current, real authorization.
Yes — the WebSocket Security Checklist is a weighted 12-point checklist covering Origin validation, connection-level authentication, message rate and size limits, and periodic re-authorization — the risks specific to persistent connections that general REST/HTTP-focused checklists typically don't cover.