Most engineering teams have a solid handle on REST API security testing. You point a scanner at your OpenAPI spec, configure authentication, and run it. But when WebSockets enter the picture, the testing model breaks down in ways that aren’t immediately obvious.
This post covers the differences between testing these two protocols from a security perspective, why your existing REST API testing approach won’t translate directly to WebSockets, and what you can do about it.
A Quick Refresher on the Protocols
If you’re reading this, you probably already know the basics, but it’s worth restating the parts that matter for security testing.
REST APIs follow a request-response pattern over HTTP. A client sends a request to a specific endpoint, the server processes it, and sends back a response. Each request is stateless and self-contained. The server doesn’t maintain an open connection between requests.
WebSockets start with an HTTP upgrade handshake, then establish a persistent, full-duplex TCP connection. Once the connection is open, both the client and server can send messages at any time without waiting for the other side. The connection stays open until one side explicitly closes it.
That persistent, bidirectional channel is what makes WebSockets useful for real-time applications like chat, live dashboards, collaborative editors, and gaming. It’s also what makes security testing fundamentally different.
| REST API | WebSocket | |
| Connection | New connection per request | Single persistent connection |
| Direction | Client → Server → Client (request-response) | Bidirectional, either side can send at any time |
| State | Stateless; each request is independent | Stateful; connection maintains context |
| Protocol | HTTP (GET, POST, PUT, DELETE, etc.) | WS/WSS over TCP after initial HTTP upgrade |
| Message format | Defined by HTTP spec + content-type headers | Application-defined (JSON, Protobuf, plain text, etc.) |
| Spec format | OpenAPI / Swagger | No widely adopted standard (AsyncAPI emerging) |

Why REST API Security Testing is Relatively Straightforward
REST API security testing benefits from a well-defined, predictable structure.
You have a map of the attack surface. REST APIs are typically described by an OpenAPI (Swagger) specification. That spec tells a scanner exactly which endpoints exist, what HTTP methods they accept, what parameters they expect, and what the request/response formats look like. The scanner doesn’t have to guess.
With StackHawk, you point HawkScan at your OpenAPI spec in stackhawk.yml, and the scanner pre-seeds its sitemap with every route defined in the spec. It knows how to construct valid requests for each endpoint, which means it can test more thoroughly and with fewer false positives. You can provide the spec as a URL path served by the app, a local file, or inline in the configuration:
app:
applicationId: xxxx-XXXX-xxxx-XXXX-xxxxxxxxxxxx
host: http://localhost:8080
openApiConf:
path: “/v3/api-docs”
Each request is independent. Because REST is stateless, a scanner can test endpoints in any order. It can send a malicious payload to /api/users/{id} without worrying about how a previous request to /api/auth might have changed the connection state. This makes parallelization and automation straightforward.
HTTP semantics give you structure. REST uses standard HTTP methods (GET, POST, PUT, DELETE), standard status codes, and standard headers. Security tooling has had decades to mature around these conventions. Authentication tokens go in headers. Input goes in query parameters, path parameters, or request bodies. A scanner knows where to inject test payloads because the protocol itself defines the input surface.
Vulnerability categories are well-established. The OWASP API Security Top 10 maps cleanly to REST APIs. Broken Object Level Authorization (BOLA), where User A’s token can access User B’s data, is testable by replaying requests with different auth tokens. SQL injection, XSS, and other injection attacks target known input vectors. Security scanners like HawkScan are built to test these categories systematically.
Where WebSocket Testing Differs
Now consider what happens when you try to apply that same approach to WebSockets. Most of the assumptions that make REST testing work don’t apply.
No Equivalent of an OpenAPI Spec
This is the biggest gap. WebSocket APIs don’t have a widely adopted, standardized specification format. There’s no equivalent of an OpenAPI spec that tells a scanner “here are the message types this WebSocket endpoint accepts, here are the fields in each message, and here are the valid values.”
Some teams use AsyncAPI to document their event-driven APIs, and it does support WebSocket bindings. But adoption is nowhere near OpenAPI levels, and most DAST tools don’t consume AsyncAPI specs to drive automated scanning. Without a machine-readable description of the message protocol, a scanner has no way to automatically enumerate and test the API surface.
Messages Are Freeform
REST APIs have structure at the HTTP level. WebSocket messages are just bytes on a wire. The application defines whatever message format it wants: JSON, Protocol Buffers, MessagePack, plain text, or something custom. There’s no standard way for a scanner to know what a valid message looks like, let alone how to construct a malicious one.
In practice, most WebSocket APIs use JSON, but the schema is application-defined and typically undocumented in a machine-readable format. A scanner that wants to fuzz WebSocket messages needs to understand the application’s specific message protocol, which usually means custom tooling or manual configuration.
Stateful Connections
Because REST is stateless, a scanner can test any endpoint independently. WebSockets are the opposite. The connection has a state, and that state changes over time as messages flow in both directions.
Consider a WebSocket-based chat application. A client might need to connect, send an authentication message, and join a room, and only then can it send and receive chat messages. A scanner can’t just send payloads at the WebSocket endpoint. It needs to follow the correct message sequence to reach a testable state. And the server’s behavior on message N might depend on what happened in messages 1 through N-1.

Authentication Works Differently
REST API authentication is well-standardized. Tokens go in the Authorization header. Cookies travel with requests automatically. A scanner can be configured with credentials once and apply them to every request.
WebSocket authentication is more varied. The initial HTTP upgrade handshake may use cookies or headers, but after that, the connection is a raw TCP channel. Many applications implement their own authentication at the WebSocket message level, where the first message after connecting might be a JSON payload containing a token. Some applications authenticate during the handshake and then trust the connection for its lifetime. Others require re-authentication for certain operations.
The OWASP WebSocket Security Cheat Sheet specifically calls this out: WebSockets have no built-in mechanism for authentication or authorization. It’s entirely up to the application to implement these correctly, which means it’s also up to the tester to understand how they’re implemented for each specific application.
Traditional Security Tools Have Blind Spots
Standard HTTP-level security tooling (WAFs, DLP systems, request loggers) was built for the request-response model. WebSocket traffic passes through these tools during the initial handshake, but deep inspection and logging of subsequent frames are inconsistent across WAFs/gateways and often disabled by default.
WebSocket frames also use client-to-server masking (as required by RFC 6455), which means the raw bytes on the wire are XOR-masked. This isn’t encryption, but it means any tool that isn’t WebSocket-aware must first unmask frames to inspect payloads
Cross-Site WebSocket Hijacking
Cross-Site WebSocket Hijacking (CSWSH) is a vulnerability class specific to WebSockets. It’s similar to CSRF, but can be higher impact because the attacker’s page can both send and receive messages once connected.
Here’s how it works. If a WebSocket server doesn’t validate the Origin header during the upgrade handshake, a malicious website can open a WebSocket connection to the vulnerable server using the victim’s cookies. Because WebSocket connections carry cookies automatically (just like regular HTTP requests), the malicious site gets an authenticated connection. And unlike CSRF against REST endpoints, the attacker’s page receives every message the server sends over that connection.

Testing for CSWSH requires checking whether the server validates the Origin header during the WebSocket handshake, something REST-focused scanners don’t typically do.
OWASP Risks: REST vs. WebSocket
The same vulnerability categories affect both protocols, but they show up differently.
| Vulnerability | REST API | WebSocket |
| Injection (SQLi, XSS) | Payloads target query params, path params, and request body fields | Payloads go inside WebSocket messages; same risk if the server doesn’t sanitize message content |
| Broken Authentication | Missing or weak token validation on specific endpoints | Auth may only happen at connection time, with no per-message validation |
| Broken Authorization | BOLA: User A’s token accesses User B’s data at a specific endpoint | User may be authenticated but able to send message types or access channels they shouldn’t |
| Denial of Service | Rate-limited at the HTTP level using standard middleware | Persistent connections can flood the server with messages, bypassing HTTP-level rate limits |
| Data Exposure | Sensitive data in response bodies, headers, or error messages | Sensitive data in WebSocket messages; harder to monitor since traffic bypasses standard HTTP logging |
| CSRF / Hijacking | Standard CSRF: attacker triggers state-changing requests using the victim’s cookies | CSWSH: attacker opens an authenticated WebSocket and reads all server responses |
DAST Scanner Compatibility
Another way to see the gap: what a typical DAST scanner can do automatically with each protocol.
| Scanner Capability | REST API | WebSocket |
| API discovery from spec | Yes (OpenAPI/Swagger) | No widely adopted spec format |
| Automated endpoint enumeration | Yes, from spec or spidering | Limited; requires understanding the message protocol |
| Payload injection | Automated across all input vectors | Requires knowledge of message schema |
| Authentication handling | Standard header/cookie config | Application-specific; often requires custom setup |
| Stateful test sequences | Not needed; requests are independent | Required; must replay message sequences to reach a testable state |
| CI/CD integration | Mature (StackHawk, etc.) | Mostly manual or semi-automated |
Where StackHawk Fits
StackHawk’s DAST scanner, HawkScan, is built for the protocols where automated security testing is most mature: REST, GraphQL, SOAP, and gRPC. For REST APIs in particular, you provide an OpenAPI spec, configure authentication, and HawkScan tests your running application against the OWASP API Security Top 10 and beyond, all within your CI/CD pipeline.
On the WebSocket side, StackHawk’s API Discovery feature can identify WebSocket endpoints in your source code repositories alongside your REST, GraphQL, and gRPC endpoints. This gives you visibility into your full API attack surface, including WebSocket services that might otherwise go untracked. Knowing where your WebSocket endpoints are is the first step toward making sure they’re properly secured.
While StackHawk can detect that a WebSocket endpoint exists, StackHawk focuses on the underlying API logic behind it. WebSockets are typically just a delivery mechanism for data that eventually hits your REST or GraphQL backend. By scanning those primary APIs with StackHawk, you are testing the actual logic where vulnerabilities live, rather than just the ‘pipe’ used to move the data.
Practical Recommendations
If your application uses both REST APIs and WebSockets, here’s a reasonable approach to security testing.
For REST APIs: Automate DAST in your CI/CD pipeline. Use a tool like StackHawk that consumes your OpenAPI spec and runs on every pull request. See the StackHawk getting started docs and the OpenAPI configuration guide if you haven’t set this up yet.
For WebSockets: Start with discovery. Use StackHawk’s API Discovery to make sure you know where all your WebSocket endpoints are. Then, focus manual security review on the areas where WebSockets diverge most from REST:
- Origin validation — Does your WebSocket server check the Origin header during the upgrade handshake? If not, you’re vulnerable to CSWSH. That said, don’t rely only on Origin; consider explicit auth in the WS protocol (token in first message) and session-bound anti-CSRF protections where appropriate.
- Authentication and authorization — How does your WebSocket connection authenticate? Is authorization checked on a per-message basis, or only at connection time?
- Input validation — Are you sanitizing the contents of WebSocket messages before using them in queries, rendering them, or passing them to other systems?
- Connection limits — Do you enforce limits on concurrent connections, message rates, and message sizes? Without these, a single client can DoS your WebSocket server.
- Encryption — Are you using wss:// (WebSocket over TLS) rather than ws:// for anything handling sensitive data?
These checks map directly to the OWASP WebSocket Security Cheat Sheet and the OWASP Testing Guide section on WebSockets.
Summary
REST API security testing has mature tools, specs, and workflows to automate it. WebSocket security testing is not there yet. The lack of a universal spec format, stateful connections, and application-defined message protocols means that WebSocket testing requires more manual effort and application-specific knowledge.
The vulnerability categories are the same: injection, broken auth, insufficient authorization, and DoS. If you understand what to test for in REST APIs, you understand what to test for in WebSocket APIs. The difference is in how you test, not what you test for. Ready to automate REST API security testing? Get started with StackHawk and run your first scan in minutes.