Skip to content

Denial-of-Service Attack Against the HTTP/3 Stack via QPACK Blocked Decoding

High
phlax published GHSA-p7c7-7c47-pwch Jun 23, 2026

Package

github.com/envoyproxy/envoy

Affected versions

<1.39

Patched versions

1.35.13 1.36.9 1.37.5 1.38.3

Description

This issue was reported publicly as: google/quiche#105

Quoting from the report:

Vulnerability Description
The issue is not a simple QPACK decoding failure. The root cause is that, when a QPACK header block becomes blocked waiting for dynamic table updates, the corresponding HTTP/3 HEADERS payload bytes are accounted for as consumed by the QUIC receive-flow-control path, while the same bytes are still retained in an internal heap buffer inside the QPACK decoder.

In the affected design, HEADERS frame payload is delivered progressively to the HTTP/3/QPACK layer rather than being fully buffered and bounded before processing. If the header block prefix declares a Required Insert Count that depends on dynamic table entries not yet received on the QPACK encoder stream, the decoder enters a blocked state. Once blocked, subsequent header block bytes are appended to an internal decoder buffer and are not semantically decoded until the required dynamic table insertions arrive.

However, on the request stream path, the implementation still marks the received payload as consumed after each decode call. As a result, stream-level and connection-level flow-control windows are returned to the peer even though the payload bytes are still resident in heap memory. This creates a discrepancy between protocol-level accounting and actual memory retention.

Because HTTP/3 HEADERS frames are processed in a streaming manner and are not subject to the buffered-frame payload cap used for certain other HTTP/3 frame types, and because the blocked-stream limit only constrains the number of concurrently blocked header blocks rather than the retained size of each blocked block, an attacker can keep feeding additional HEADERS payload bytes into the hidden decoder-side heap buffer. In practice, this can lead to unbounded memory growth and denial of service of the HTTP/3 stack.

In one sentence, the vulnerability can be summarized as follows:

During blocked QPACK decoding, HEADERS payload is released from QUIC receive-flow-control accounting before it becomes safely releasable in memory, causing the payload to accumulate in an internal heap buffer that is no longer effectively bounded by QUIC flow control.

Attack Preconditions
The target uses IETF QUIC with HTTP/3 enabled.
The server supports the QPACK dynamic table.
The server permits blocked QPACK streams (commonly with QPACK_BLOCKED_STREAMS = 100 by default, or another non-zero value).
The attacker can establish at least one normal HTTP/3 connection to the target service.
The attacker can send a syntactically valid HEADERS frame whose QPACK header block prefix declares dependence on a dynamic table entry that has not yet arrived.
In deployments using google/quiche as the HTTP/3 server core, these conditions are met by default. Therefore, no additional privileges, authentication, or special access are required beyond the ability to interact with the service as a normal remote HTTP/3 client.

Impact

Attacker can send unbounded data which will be buffered internally in the HTTP/3 stack, resulting in an out-of-memory condition.

Patches

Has the problem been patched? What versions should users upgrade to?

Workarounds

No

References

google/quiche#105

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

CVE ID

No known CVE

Weaknesses

No CWEs