WebSocket security testing: what assessments find that code reviews miss

Key takeaways
WSS encrypts the transport layer only — it does not protect against authentication bypass, message injection, or session hijacking inside the connection.
In 68% of Vulnox assessments where WebSockets were in use, server-side origin validation was absent or trivially spoofable via a crafted Origin header.
HTTP rate limiting does not apply to WebSocket connections. A single authenticated connection can flood a server with thousands of messages before any HTTP-layer control fires.
Teams with mature security programs were more likely to have undetected WebSocket flaws — their tooling and test coverage was built for HTTP, and they assumed coverage transferred.
74% of assessed real-time applications lacked input validation on WebSocket messages, making stored XSS and message injection the most common critical finding in this class of assessment.
JWT authentication for WebSockets fails in practice when tokens are validated at handshake only and never re-checked — a session valid at 9am stays valid after the token expires at noon.
TL;DR
WebSocket security fails in a specific, predictable way: teams apply HTTP security thinking to a protocol that does not work like HTTP. Origin validation gets skipped. Input validation stops at the API boundary and never reaches the message handler. Rate limiting sits on the load balancer and sees nothing after the handshake completes. The result is a persistent, authenticated channel with fewer controls than the REST API sitting next to it. This article covers what assessments actually find and why code review alone will not catch it.
A fintech with a clean pentest report and an open WebSocket
A 35-person fintech processing roughly €2M per day in real-time FX transactions came in after a clean penetration test. External pentest, scoped to their web application. The report showed two medium findings, both remediated. Their security posture, on paper, was fine. We ran a WebSocket-specific assessment as part of a broader engagement. Within six hours we had identified a message injection path that allowed an authenticated user to submit trade orders using another users session context. The WebSocket connection authenticated at handshake using a short-lived JWT. The JWT expired after four hours. The server never re-validated it. A token stolen via a separate low-severity XSS — the kind that gets downgraded in triage — would keep an attacker inside a live trading session for the rest of the business day.
The previous pentest did not test WebSocket message-level authorization. The scope said 'web application.' The testers tested the web application. WebSockets were in the application but outside the mental model. Nobody lied. Nobody was negligent. The coverage gap was structural.
Why HTTP security thinking breaks on WebSocket connections
HTTP is stateless and request-driven. Every request carries credentials. Every response ends the transaction. Security controls — authentication middleware, rate limiting, WAF rules, input validation filters — are designed around that model. One request in, one response out, controls applied per-transaction. WebSockets are none of that. The handshake is HTTP. Everything after it is a persistent, bidirectional TCP stream. Once the connection upgrades, the HTTP layer is gone. WAF rules that inspect HTTP request bodies do not see WebSocket frames. Rate limiters counting HTTP requests do not count WebSocket messages. Authentication middleware that runs on every HTTP route does not run again on a live WebSocket session. The controls that your team spent years building and your auditors spent time verifying are simply not in the path.
Example
A load balancer configured to block requests containing SQL injection signatures will pass WebSocket frames containing those same strings without inspection. The WAF rule fires on the Content-Type and method of an HTTP request. A WebSocket frame has neither. This is not a WAF misconfiguration. It is a protocol boundary that most WAF deployments do not cross by default. Checking your WAF vendor documentation for WebSocket frame inspection support is not optional — it is the difference between a control that works and one that creates false confidence.
The WebSocket upgrade request is HTTP and will be inspected by controls in the HTTP path. The upgraded connection is not. Any security control that relies on HTTP request/response semantics — headers, methods, status codes, cookies as authentication tokens — operates only during the handshake phase. After upgrade, the connection is a raw TCP stream framed by the WebSocket protocol. Controls must be reimplemented at the application layer, inside the message handler, not at the network or HTTP layer.
What the numbers actually look like across real assessments
68%
Of client environments assessed by Vulnox where WebSockets were in use, server-side origin validation was absent or bypassable. The Origin header in the WebSocket handshake can be set to any value by the client. Servers that do not validate it against an allowlist accept connections from any domain. (Vulnox assessment data, 2024, n=47)
74%
Of assessed real-time applications had no input validation on WebSocket message payloads. Data arriving over the WebSocket was parsed and processed without sanitization. Stored XSS and server-side injection were the most common exploitable results. (Vulnox assessment data, 2024)
62%
Of applications exposed internal diagnostic information — stack traces, internal IP addresses, dependency versions — through WebSocket error responses. This is reconnaissance delivered by the application itself. (Vulnox assessment data, 2024)
43%
Of financial services clients using WebSockets for real-time market data had no message integrity checks. Messages could be modified in transit or injected by a man-in-the-middle on a network without TLS pinning. (Vulnox assessment data, 2024)
What assessments find that code reviews miss
Assessment base: 47 client environments assessed with active WebSocket implementations, 2023–2024
Session tokens validated at handshake, never again
In 31 of 47 assessed environments, JWT or session token validation occurred exactly once — during the WebSocket upgrade handshake. After the connection was established, the server made no further checks. Tokens with four-hour expiry windows kept connections alive past expiry. In two cases, tokens were invalidated server-side (logout, password change) while active WebSocket sessions remained open and fully functional.
The client believed their token expiry policy protected against session persistence after logout. It did not. A stolen token that reaches a WebSocket handshake before revocation produces a session that outlives the token. The revocation system and the WebSocket session lifecycle were never designed to interact.
Developers treated WebSocket message handlers like internal functions
In the majority of applications with injection vulnerabilities, the message handler — the function receiving and processing incoming WebSocket messages — had no input validation. The developers who wrote it treated it like an internal API called by trusted code. From their perspective during development, it was. The WebSocket client was their own frontend. The message schema was their own design. Nobody modeled an attacker sending arbitrary frames to that handler directly.
WebSocket endpoints are externally reachable. Any client that can initiate a WebSocket connection — including a script running in a browser tab on another domain, if origin validation is absent — can send arbitrary message content to that handler. Treating the message handler as a trusted internal boundary is the root cause of the majority of injection findings in this class of application.
More mature security programs had larger WebSocket blind spots
This one surprised the clients. Organizations with dedicated security teams, annual pentests, and vulnerability management programs had a higher rate of undetected WebSocket vulnerabilities than smaller organizations with less formal programs. The pattern was consistent enough to be notable.
Mature programs build coverage systematically. That means their tooling, test cases, training, and scanner configurations are built around what they have historically needed to cover. HTTP application security. That coverage is real and valuable. But it creates a blind spot for anything that does not fit the HTTP model. WebSocket testing was not in scope historically, so it is not in scope now. The team assumes the controls transfer. The assessment shows they do not.
The four gaps that consistently survive internal reviews
CSRF on WebSocket connections
Most developers correctly know that WebSocket connections do not use cookies in the same way as HTTP requests and conclude CSRF is not applicable. This is partially wrong. A malicious page can initiate a WebSocket connection to a target application in the context of an authenticated user's browser session — including sending the session cookie during the HTTP upgrade handshake if the server accepts cookie-based authentication. The connection upgrades. The malicious page now has a live WebSocket channel to the application, authenticated as the victim. The browser's same-origin policy blocks reading the response in some configurations, but it does not block the connection or sending messages.
DoS via connection exhaustion, not message volume
Teams model WebSocket DoS as high message volume — a client sending thousands of messages per second. They build rate limiters around message frequency. The more reliable attack against applications without connection limits is simpler: open thousands of connections, send nothing, hold them open. WebSocket servers allocate memory and file descriptors per connection. A server configured to allow 10,000 concurrent connections will exhaust memory before a rate limiter based on message count fires once.
Subprotocol negotiation as an attack surface
WebSocket connections support subprotocol negotiation — the client requests a protocol ('Sec-WebSocket-Protocol: chat, v2.chat') and the server selects one. In 19 of 47 assessed environments, the server accepted arbitrary subprotocol strings without validation, reflected the client-supplied value in the handshake response, and in three cases, branched application logic based on the subprotocol value without sanitizing it. This is a small but consistent finding that scanner tools miss entirely because they do not model subprotocol negotiation.
Logging that captures HTTP but not WebSocket frames
Security monitoring and SIEM integrations are built around HTTP logs. Access logs, WAF logs, application logs structured around request/response cycles. WebSocket frames are usually logged at the application layer if at all, and often not forwarded to the SIEM. The practical result: an attacker operating entirely within WebSocket sessions generates no HTTP log entries after the initial upgrade. Lateral movement, data exfiltration, command injection — all of it happens in a channel that the SOC is not watching.
What clients say before the assessment, and what is actually underneath it
'We use WSS everywhere. The connection is encrypted. We focused our security testing on the HTTP endpoints because that's where the sensitive data flows.'
Root cause:WSS is TLS for the WebSocket transport. It prevents eavesdropping and tampering in transit. It has no effect on what an authenticated client sends over the encrypted channel, who is allowed to connect, or whether message content is validated before processing. Encryption and access control are separate problems. Solving one does not address the other. The sensitive data flows over WebSockets too — it just flows encrypted, which means an attacker with a valid session receives it encrypted and decrypts it on their end.
'Our developers said our existing rate limiting covers WebSocket traffic too.'
Root cause:The rate limiter is on the load balancer or API gateway. It counts HTTP requests. After a WebSocket connection upgrades, traffic flows as TCP frames. The load balancer sees one long-lived connection, not individual messages. Message-level rate limiting must be implemented inside the WebSocket server, in the message handler, counting frames per connection per unit time. This is a separate implementation from HTTP rate limiting and must be built explicitly. In 41 of 47 assessed environments, it had not been.
'We had a penetration test six months ago. It came back clean on the application.'
Root cause:Penetration test scope is negotiated before the engagement. 'Web application' scope typically means the tester evaluates the HTTP application — login flows, session management, input validation on form fields and API endpoints. WebSocket testing requires specialized tooling (Burp Suite with WebSocket support configured, or custom scripts), a test plan that covers the WebSocket message schema, and explicit scope authorization. Without those, a tester doing a standard web application assessment will note WebSocket endpoints in their asset inventory and move on. The clean report is accurate for the scope that was tested.
The thing that looks safe and is not: authenticated connections
Common belief
If an attacker needs to authenticate before establishing a WebSocket connection, the attack surface is limited to authenticated users. Authentication is the gate. Pass the gate, you're inside the trust boundary.
What we found
In a B2B SaaS platform with role-based access control properly implemented across all HTTP endpoints, an authenticated low-privilege user could send WebSocket messages that triggered admin-level operations — bulk user deletion, configuration changes, export of user PII. The HTTP endpoints that performed these operations checked roles correctly. The WebSocket message handler that triggered the same backend functions did not check roles at all. The developer who built the WebSocket handler was not the developer who built the authorization middleware. Nobody connected them. (Vulnox assessment data, 2024)
Authentication establishes identity. It does not establish what that identity is permitted to do within a WebSocket session. In eight of 47 assessed environments, we found that authenticated WebSocket connections had no message-level authorization. Any authenticated user could send any message type to any other user's session context — not by breaking authentication, but by sending a message the server was not checking authorization on. The session was authenticated. The messages inside it were not. The gate was real. The room behind it had no walls.
What to actually fix, in sequence
Step 6. Teams log HTTP traffic comprehensively and assume coverage. WebSocket sessions run unlogged through SOC monitoring tools for months before anyone notices the gap. By that point, an attacker who found the channel has had quiet, authenticated access to whatever the WebSocket session could reach.
- 1Security architect or lead developer
Inventory every WebSocket endpoint in the application. Not the ones you know about — all of them. Run a spider or proxy all traffic through Burp Suite to catch WebSocket connections initiated by frontend JavaScript that are not in the API documentation. Document the message schema: what messages are accepted, from whom, with what authentication state.
Expected outcomeA complete map of WebSocket attack surface. Most teams discover two to four undocumented WebSocket endpoints during this step.
- 2Backend developer
Implement allowlist-based Origin header validation on the WebSocket server. The server should maintain a list of permitted origins and reject the upgrade handshake for anything outside it. This must be server-side — browser enforcement is not reliable. Test it by sending an upgrade request with a crafted Origin header from a tool, not a browser.
Expected outcomeCross-site WebSocket hijacking is blocked at the handshake. Test by sending 'Origin: https://attacker.example.com' in an upgrade request and confirming the server returns 403.
- 3Backend developer
Implement input validation inside the message handler — not at the HTTP boundary, inside the WebSocket message handler itself. Validate message structure against the documented schema. Reject and close connections that send malformed messages. Apply the same sanitization to WebSocket message fields that you apply to HTTP request parameters.
Expected outcomeMessage injection, stored XSS via WebSocket, and server-side injection through message fields are blocked. This is a separate implementation from HTTP input validation and must be built explicitly.
- 4Backend developer
Add authorization checks inside the message handler for any message type that triggers a privileged operation. Do not assume that session authentication implies authorization for all message types. Check the authenticated user's role or permission set against the operation the message requests, the same way you check it on HTTP endpoints.
Expected outcomeAuthenticated low-privilege users cannot trigger admin-level operations via WebSocket messages, even with a valid session.
- 5Backend developer or platform team
Implement message-level rate limiting inside the WebSocket server. Count messages per connection per time window. Implement connection limits per authenticated user. Set a maximum message size. These three controls together prevent the most common resource exhaustion paths.
Expected outcomeConnection exhaustion and message flood attacks require orders of magnitude more resources to execute. Not prevention, but meaningful friction.
- 6Operations or security engineering
Forward WebSocket frame logs to your SIEM. If your application does not currently log WebSocket messages, implement logging for message type, sender, session ID, and timestamp. If your SIEM ingestion pipeline does not handle WebSocket log format, build the parser. An attack operating entirely through WebSocket sessions should not be invisible to your SOC.
Expected outcomeAnomalous WebSocket activity — high message rates, unusual message types, messages from inactive sessions — generates alerts that the security team can act on.
Further Reading
Vulnerability Assessment
comprehensive vulnerability assessmentDigital Footprint
digital footprint analysisNIST Vulnerability Assessment Definition
NIST's vulnerability assessment definitionOWASP Web Security Testing Guide
OWASP web security testing guideNIST SP 800-30 Risk Assessment Guide
NIST risk assessment guide
Frequently Asked Questions
Does WSS (WebSocket Secure) protect against injection attacks?
No. WSS is TLS applied to the WebSocket transport layer. It prevents eavesdropping and tampering in transit. It has no effect on what an authenticated client sends over the encrypted connection. Input validation, output encoding, and message schema enforcement must be implemented in the application layer, inside the WebSocket message handler, independently of transport encryption.
Does HTTP rate limiting protect WebSocket endpoints?
Not after the connection upgrades. HTTP rate limiters count requests. Once a WebSocket connection completes the upgrade handshake, traffic flows as persistent TCP frames. A load balancer or API gateway sees one long-lived connection, not individual messages. Message-level rate limiting must be implemented inside the WebSocket server. In 41 of 47 environments assessed by Vulnox, it had not been.
How do you test WebSocket authentication bypass?
Start by establishing a legitimate authenticated WebSocket connection through Burp Suite with WebSocket history enabled. Then test three things: send the upgrade handshake with a spoofed Origin header and confirm the server rejects it; establish a connection, wait for the session token to expire, and send messages to confirm the server re-validates; and send messages that should require elevated privileges from a low-privilege authenticated session to check whether message-level authorization is enforced separately from session authentication.
Can CSRF attacks work against WebSocket connections?
Yes, in specific conditions. A malicious page can initiate a WebSocket connection to a target application in the context of an authenticated user's browser if the server accepts cookie-based authentication during the upgrade handshake and does not enforce Origin validation. The browser sends the session cookie with the HTTP upgrade request. If the server validates only the cookie and not the Origin, the connection upgrades and the malicious page has an authenticated channel.
What does a WebSocket penetration test cover that a standard web app pentest misses?
Standard web app pentests evaluate HTTP endpoints — request/response cycles, session management via cookies and headers, input validation on form fields and API parameters. WebSocket-specific testing covers the upgrade handshake (origin validation, subprotocol negotiation), message-level authentication and authorization after the handshake completes, input validation inside WebSocket message handlers, connection and message rate limits, and whether WebSocket session lifecycle is tied to token revocation. Without explicit WebSocket scope and tooling, testers will inventory WebSocket endpoints and move on.
Why do mature security programs have worse WebSocket coverage than less formal ones?
Mature programs build systematic coverage around known risk areas. That coverage is real — their HTTP application security is usually solid. But it creates a structural blind spot: tooling, scanner configurations, test plans, and training all built for HTTP. When WebSockets are added to an application, the assumption is that existing controls transfer. In Vulnox assessment data across 47 environments, they consistently did not. Less formal programs sometimes caught WebSocket issues through general testing that accidentally exercised WebSocket endpoints, where mature programs specifically excluded them from known-good scope.
What is the fastest way to find WebSocket security flaws without a full assessment?
Proxy all application traffic through Burp Suite and enable WebSocket history. Identify every WebSocket endpoint the frontend initiates. For each one: attempt a connection with a spoofed Origin header; send a message with a SQL injection payload in every string field and check server responses; send a message that should require admin privileges from a non-admin session; let a valid session token expire and continue sending messages. These four tests will surface the most common critical findings in under a day and require no specialized tooling beyond a configured Burp Suite instance.
Related Articles

API security assessment: what automated tools miss and manual testing finds
Automated API security tools find the vulnerabilities they were designed to look for. The findings that matter in real assessments, broken object-level authorization, JWT algorithm confusion, and unauthenticated internal endpoints, require a tester who understands what the API is supposed to do before probing what it actually does.

CVSS score explained: what the metric captures, what it misses, and how to fix your prioritization
In 40% of Vulnox assessments, vulnerabilities scored CVSS 9.0 or higher were on systems with compensating controls that materially reduced the actual risk. The score was accurate. The priority order it implied was not. This guide covers how to use CVSS correctly and what to layer on top of it.

Post-breach vulnerability assessment: what the attacker left behind
Most post-breach assessments start too late and end too early. They confirm what was hit, not what the attacker mapped before they moved. The second breach usually comes from the reconnaissance that happened in the first.
Ready to Secure Your Digital Assets?
Get a comprehensive vulnerability assessment for your website today.