Safeguard
Vulnerability Management

HTTP/2 CONTINUATION Flood: Inside CVE-2024-27316 and the Frame-Based DoS Class

A single TCP connection with no END_HEADERS flag was enough to crash major HTTP/2 servers — worse than Rapid Reset, and it took the industry a decade to check for it.

Safeguard Research Team
Research
7 min read

On April 3, 2024, researcher Bartek Nowotarski disclosed a class of HTTP/2 denial-of-service bugs that CERT/CC catalogued as VU#421644, and NVD tracked the Apache HTTP Server variant as CVE-2024-27316 with a CVSS v3.1 base score of 7.5. The flaw affected Apache httpd 2.4.17 through 2.4.58 — a version range spanning roughly seven years of releases — and NVD's own description is blunt about the mechanism: incoming headers that exceed the configured limit are "temporarily buffered in nghttp2 in order to generate an informative HTTP 413 response," and if the client keeps sending headers instead of stopping, that buffer grows until the process runs out of memory. Nowotarski argued the class was potentially more severe than the record-breaking HTTP/2 Rapid Reset attacks disclosed in October 2023, because Rapid Reset needed thousands of streams to do damage, while a CONTINUATION flood could crash some implementations over a single TCP connection. Given that HTTP now accounts for the large majority of internet traffic and that CONTINUATION frames are a mandatory, unauthenticated part of the HTTP/2 spec (RFC 7540/RFC 9113), this wasn't a niche edge case — it was a gap present in the protocol's core header-parsing logic across nearly every major implementation. This post walks through how the frame type works, why it was exploitable, and how servers closed the gap.

What is a CONTINUATION frame, and why does HTTP/2 need one?

A CONTINUATION frame exists to let HTTP/2 split an oversized HEADERS block across multiple frames, because a single frame is capped by the connection's maximum frame size (16KB by default, per RFC 9113 Section 4.2). When a client or server needs to send headers larger than that limit — a long cookie, an oversized authorization token, a chatty set of custom headers — it sends an initial HEADERS frame followed by as many CONTINUATION frames as needed, and every frame in that sequence except the last must omit the END_HEADERS flag. The receiving endpoint is required to keep buffering and treat the whole sequence as one logical header block until it sees a frame with END_HEADERS set. That design is reasonable on its face: it lets HTTP/2 support arbitrarily large header sets without redesigning the framing layer. The problem is what the spec does not mandate: an upper bound on how many CONTINUATION frames can arrive, or how much memory an endpoint is allowed to spend buffering them, before it gives up and resets the stream.

Why did buffering-before-validation make servers exploitable?

Buffering-before-validation made servers exploitable because many HTTP/2 stacks checked header-size limits only after the full header block was assembled, not while it was still arriving. An attacker exploiting the class opens one HTTP/2 connection, sends a HEADERS frame, and then streams an effectively unbounded run of small CONTINUATION frames without ever setting END_HEADERS. A naive implementation dutifully appends each frame's payload to an in-memory buffer, waiting for a terminator that never comes, while CPU time spent re-parsing partial header state and memory held by the growing buffer both climb. In Apache httpd's case, the vulnerable path was specifically the code that builds an HTTP 413 ("Payload Too Large") error response: httpd correctly detected that headers exceeded its limit, but instead of terminating the stream immediately, it kept the oversized data buffered so it could compose an informative error message — and that buffering had no independent cap. The fix path across implementations converged on the same idea: reject or reset the stream the moment a size or frame-count limit is crossed, rather than after assembling anything.

Which implementations besides Apache httpd were affected?

The April 2024 disclosure round covered implementations well beyond Apache httpd. Node.js shipped CVE-2024-27983, where a small number of HTTP/2 frames could trigger a race condition and memory leak in the server's frame-handling code, patched in the April 2024 Node.js security releases. Envoy proxy shipped CVE-2024-27919, affecting its oghttp2 codec, which failed to reset a request when header-map limits were exceeded, allowing unbounded memory growth. Apache Traffic Server shipped CVE-2024-31309, affecting versions 8.0.0 through 8.1.9 and 9.0.0 through 9.2.3, fixed in 8.1.10 and 9.2.4 by adding a configurable proxy.config.http2.max_continuation_frames_per_minute setting. Tomcat, gRPC-based stacks, and several other HTTP/2 libraries received their own advisories in the same window. The breadth mattered: because nearly every modern web stack speaks HTTP/2 by default, this wasn't a single-vendor bug but a validation gap that had been quietly reproduced across a decade of independent RFC 7540 implementations.

How is this different from HTTP/2 Rapid Reset?

CONTINUATION flood and Rapid Reset (CVE-2023-44487) both abuse HTTP/2's stream model, but they attack different resources and at different scale. Rapid Reset, disclosed in October 2023 after being exploited since August 2023 in attacks Cloudflare, Google, and AWS all reported mitigating at record request volumes, works by opening a stream and immediately cancelling it with RST_STREAM, then repeating that thousands of times per connection to exhaust server-side request-processing capacity while dodging the server's max-concurrent-streams limit. CONTINUATION flood instead targets memory and header-parsing CPU time directly, and — critically — some vulnerable implementations could be knocked over with a single stream on a single connection, requiring none of the volumetric scale Rapid Reset needed. That single-connection property is what made Nowotarski's disclosure notable to defenders: a rate limiter tuned to catch thousands of requests per second from one IP would never see this attack coming, because it can look like one slow, quiet connection.

How should web servers mitigate the CONTINUATION flood class?

Mitigation converges on three concrete controls, all aimed at rejecting bad input before it accumulates rather than after. First, cap the total size of a header block and the number of CONTINUATION frames permitted per stream — Apache Traffic Server's max_continuation_frames_per_minute setting and equivalent per-stream header-list-size limits in Envoy and nghttp2 both implement this directly. Second, enforce that limit incrementally, frame by frame, and reset the stream (RST_STREAM) or close the connection the instant the limit is crossed, instead of buffering to compose a polite error response — the exact behavior NVD's CVE-2024-27316 writeup identifies as the root cause. Third, apply idle and total-stream timeouts so a connection that never sends END_HEADERS gets torn down regardless of buffer size. Operators running any of the affected version ranges should confirm they are patched — Apache httpd 2.4.59 or later, Traffic Server 8.1.10/9.2.4 or later, current Node.js and Envoy releases — since the fix is a version upgrade, not a configuration workaround alone.

How Safeguard Helps

Protocol-level flaws like CVE-2024-27316 live in the web server and proxy layer, not in application code, which is exactly the kind of exposure a vulnerability-management program has to catch through dependency and infrastructure tracking rather than SAST. Safeguard ingests CVE data from NVD, OSV, and GHSA continuously and re-evaluates every project the moment a new CVE like this one is published, so an Apache httpd or Traffic Server version pinned in a Dockerfile or infrastructure manifest gets flagged without waiting for a manual audit. Griffin AI then prioritizes it using EPSS exploit-probability scoring, CISA KEV status, and exploitability signals, so a high-severity, network-exploitable DoS bug like CVE-2024-27316 surfaces ahead of theoretical findings that pose less real-world risk — helping teams triage the next protocol-level advisory in minutes instead of days.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.