How it works
A single connection can carry many concurrent streams, so protocol-level abuse multiplies work per connection rather than per request. Streams are opened and immediately cancelled, header blocks are sent that never terminate, or upgraded connections are held and reconnected to consume server state.
Efficiency features become force multipliers
HTTP/1.1 tied requests to connections, which incidentally rate-limited clients: to make more requests you opened more connections, and connections are visible and countable.
HTTP/2 removed that coupling deliberately. One connection carries many concurrent streams, which is excellent for real users and removes the natural governor. A client that would previously have needed hundreds of connections to generate high request volume now needs one, and the countermeasures built around connection counting no longer see anything unusual.
The same applies to WebSocket. An upgraded connection is long-lived by design and often carries subscriptions that make the server do work whenever anything happens elsewhere in the system — which means the cost of a connection is no longer bounded by what its own client sends.
Neither protocol is badly designed. Both simply moved the unit of abuse from the connection to something the surrounding defences were not counting.
Rapid reset
The rapid reset technique exploits the gap between when a server begins work and when it learns the client no longer wants it. A client opens a stream, the server starts processing, and the client immediately sends a cancellation. The stream slot is freed straight away, so the client can open another — and the concurrent-stream limit, which is the obvious control, never binds because no stream stays open.
The server meanwhile has begun and must unwind work for every one of those streams. Request rates far beyond what the connection limit was intended to permit become achievable from a small number of connections.
This was assigned a CVE and patched widely, which makes patch currency the first control. The durable mitigation is to rate-limit resets rather than only concurrency: a connection cancelling streams far more often than it completes them is behaving in a way no legitimate client does, and it can be throttled or closed on that basis.
CONTINUATION and header-block abuse
HTTP/2 sends headers as a compressed block which may be split across continuation frames. Some implementations accumulated those frames without bounding the total, so a client sending an unterminated sequence could drive memory or CPU consumption arbitrarily.
Two properties made this dangerous. The traffic often did not appear in request logs, because no complete request was ever formed — the server was consuming resources on something it never counted as a request. And the impact varied sharply between implementations, so a service could be severely affected while an identically configured peer running different software was untouched.
The controls are bounds and placement: cap total header block size and header count explicitly rather than relying on defaults, and terminate HTTP/2 at a proxy that is updated aggressively, so application servers behind it never parse hostile protocol input.
WebSocket exhaustion
WebSocket attacks come in three shapes, and they differ in what they consume.
Connection holding is the simplest: open many upgraded connections and keep them idle. Each consumes memory, a file descriptor and often a slot in a subscription registry, and unlike an HTTP request none of it is released by a timeout because idleness is normal.
Reconnect storms invert it, connecting and disconnecting rapidly so the server repeatedly performs setup — authentication, session lookup, subscription registration — which is far more expensive than steady state.
Subscription abuse is the most damaging, because it makes other users' activity expensive. A client subscribing to a large number of channels causes fan-out work on every event, so a handful of connections can multiply the cost of ordinary traffic across the whole system.
The governing rule is to authenticate before doing anything expensive. Subscription registration, channel joins and history replay should require an identity that can be limited and revoked, never merely a completed upgrade.
Detection and posture
Per-connection ratios are the signal here, because per-request and per-connection counts both look normal.
- Streams opened versus streams completed per connection — a wide gap is rapid reset.
- Reset frames per connection per second, alerted on directly.
- Memory per connection, which is where header-block abuse becomes visible.
- Requests per connection distribution: a small number of connections carrying an outsized share of total requests.
- WebSocket reconnect rate and the ratio of idle to active sessions.
- Subscription counts per connection, and fan-out queue depth as a leading indicator of broadcast overload.
Also known as
What defenders may observe
- Unusually high stream reset rate per connection
- Very high request rates over comparatively few sessions
- HTTP/2 parser errors or steadily growing memory
- Abnormal continuation sequences from particular clients
- WebSocket concurrency or reconnect rate spikes with idle sessions dominating
- Fan-out queues and broadcast memory grow without user growth
Prevention and mitigation
- Patch HTTP/2 implementations promptly — several of these are implementation bugs with fixes
- Terminate HTTP/2 at a hardened, updated proxy rather than at application servers
- Limit concurrent streams, and rate-limit stream resets per connection
- Bound header block size and total header count
- Authenticate before permitting expensive subscriptions or broadcasts
- Apply idle, lifetime and per-account limits to upgraded connections with bounded fan-out
Initial response priorities
- Activate application-aware edge controls and origin shielding.
- Identify the expensive route, query or protocol behavior.
- Challenge, rate-limit or shed abusive work while preserving normal users.
Use your approved incident-response plan and adapt decisions to your environment. This is educational guidance, not a substitute for live incident leadership.