Loading...

Executive Summary

On June 3, 2026, security researchers publicly disclosed a remote denial-of-service vulnerability named the HTTP/2 Bomb. Discovered by OpenAI Codex, the attack chains two decade-old HTTP/2 techniques — an HPACK indexed-reference compression bomb and a Slowloris-style flow control stall — into a combined exploit that neither technique alone could achieve. A single attacker on a 100 Mbps home connection can exhaust 32 GB of server RAM in 10 seconds with no authentication, no misconfiguration required, and no specialized tooling beyond the published proof-of-concept.

This report covers the technical architecture of the attack, the root cause in HTTP/2 implementations, amplification ratios across affected servers, and remediation guidance. The core finding is an insecure-by-design header field count enforcement model present in default configurations of NGINX, Apache HTTPD, Microsoft IIS, Envoy, and Cloudflare Pingora — affecting over 880,000 publicly exposed servers at time of disclosure.

T1499 - Endpoint Denial of Service T1499.001 - OS/Kernel Exhaustion T1499.002 - Service Exhaustion Flood T1071.001 - Web Protocols CVE-2026-49975 CVSS 9.8 Critical
HTTP/2 BOMB — BY THE NUMBERS
880K+
Exposed Servers 
10s
To Exhaust 32 GB 
5,700:1
Peak Amplification Ratio
9.8
CVSS v3 Score (Critical)

Background: HTTP/2 and HPACK

HTTP/2 replaced HTTP/1.1's plaintext header repetition with a binary framing layer and a header compression scheme called HPACK (RFC 7541). HPACK maintains a dynamic table shared between client and server — a rolling list of previously seen header name-value pairs. Once a header is in the table, the sender can reference it with a single-byte index instead of transmitting the full header again.

HTTP/2 also includes a flow control mechanism to prevent fast senders from overwhelming slow receivers. Each connection carries a flow control window — a byte credit the sender must not exceed. The receiver controls this window and can set it to any value, including zero.

Both features are correct implementations of their specifications. The vulnerability is not a bug in the spec — it is the consequence of two legitimate features composing into an exploitable behavior that server implementations failed to account for.

Architecture of the Attack

The HTTP/2 Bomb chains two independent techniques into a single exploit. Neither technique alone causes catastrophic damage. Together, they produce a memory exhaustion attack that is both trivial to execute and nearly impossible to defend against without patching.

Technique 1 — HPACK Indexed-Reference Bomb

The attacker crafts an HTTP/2 request that inserts a small header entry (("a", "")) into the server's HPACK dynamic table using a literal with incremental indexing representation, then emits thousands of single-byte indexed references (0xBE) pointing back to that entry. Each 0xBE byte on the wire forces the server to fully reconstruct the referenced header, allocating real memory for each occurrence.

Key Finding

The root cause is not HPACK itself — it is that servers enforce a maximum decoded header size but not a maximum header field count. Both limits are needed. With only a size limit, an attacker uses headers with a 1-byte name and 0-byte value (a: ) to slip thousands of references under the size threshold while triggering massive allocation counts.

Technique 2 — Flow Control Window Stall

At the HTTP/2 handshake, the attacker sets INITIAL_WINDOW_SIZE = 0. With a zero-byte window, the server cannot transmit any response data — all allocated state is held indefinitely. To prevent timeout-based cleanup, the attacker periodically sends 1-byte WINDOW_UPDATE frames, resetting the server's send timeout timer without ever permitting an actual response to complete.

Execution Flow

HTTP/2 BOMB — ATTACK EXECUTION CHAIN
1
TLS + HTTP/2 Handshake
Attacker opens a TLS connection with ALPN h2. Sends client preface + SETTINGS frame with INITIAL_WINDOW_SIZE = 0 and ENABLE_PUSH = 0. Server flow control is frozen from the first frame.
2
Dynamic Table Seeding
Attacker sends a HEADERS frame containing standard pseudo-headers plus a literal-with-indexing insertion of ("a", "") into the dynamic table at index 62. One entry, ~38–59 bytes on the server.
3
Indexed Reference Flood
32,000 bytes of 0xBE sent — each a 1-byte indexed reference to dynamic entry 62. Server allocates ~59 bytes per reference = ~1.9 MB per stream. Across 128 streams per connection: ~240 MB per connection.
4
Memory Hold via Window Drip
Attacker drips 1-byte WINDOW_UPDATE frames every ~50 seconds. Server cannot respond, cannot free memory. All allocated state pinned indefinitely. 15 parallel connections = ~4 GB held against a single NGINX worker.
5
Server OOM / Crash
Worker process exhausts available RAM. OOM killer terminates the process or the server becomes unresponsive. All legitimate connections dropped. Attack can be sustained or repeated to prevent recovery.
HOW THE HTTP/2 BOMB WORKS — VISUAL BREAKDOWN
Part 1 — The Memory Amplification
Attacker Sends
1 byte
a single indexed reference
amplifies to
5,700×
Server Allocates
5,700 bytes
of server RAM consumed
Send 32,000 of these references per stream → server allocates ~280 MB per connection
Part 2 — Why the Server Can't Free the Memory
Normal behaviour
Server processes a request → sends a response → frees the memory it allocated. The cycle completes and RAM is reclaimed.
Under attack
Attacker sets the response window to zero bytes. Server is blocked from sending anything. Memory is allocated but the cycle never completes — RAM stays consumed forever.
Keeping it alive
To stop the server timing out and closing the connection, the attacker sends a tiny 1-byte "heartbeat" every 50 seconds — just enough to reset the clock, never enough to unblock the response.
Part 3 — How One Machine Takes Down a Server
1
machine
×
15
connections
×
128
streams each
×
~280 MB
per connection
=
~4 GB
server RAM gone
in under a minute

Proof-of-Concept Code

Researchers published working PoC scripts for all five affected servers. The scripts were generated by Codex and kept unedited as a historical artifact. Both use zero external dependencies — pure Python stdlib only.

NGINX Bomb Builder

hpack_bomb.py — NGINX PoC
def build_hpack_bomb(num_headers):
block = bytearray()
# Pseudo-headers via static table — 1 byte each
block.append(0x80 | 2)   # :method GET
block.append(0x80 | 4)   # :path /
block.append(0x80 | 6)   # :scheme https
block.append(0x41)       # :authority — literal with indexing
block.append(0x01)
block.append(ord("x"))
# Insert bomb entry: ("a", "") → dynamic table at index 62
block.append(0x40)       # literal with indexing, new name
block.append(0x01)       # name length = 1
block.append(ord("a"))   # name = "a"
block.append(0x00)       # value length = 0 (empty)
# 0xBE = indexed reference to dynamic entry 62
# 1 byte on wire → 59 bytes allocated on server
# 3 bytes in state.pool + 56 bytes in ngx_table_elt_t
refs = num_headers - 5
block.extend(b"\xbe" * refs)   # ← THE BOMB
return bytes(block)
Flow Control Stall
# At handshake — freeze the server's flow control window
settings_frame([
(SETTINGS_ENABLE_PUSH, 0),
(SETTINGS_INITIAL_WINDOW_SIZE, 0),  # server cannot send, cannot free memory
])
# Hold phase — drip 1 byte every 50s to reset server timeouts
window_update_frame(0, 1)           # connection-level
window_update_frame(stream_id, 1)   # per-stream

Apache HTTPD — Cookie Bypass

Apache's mod_http2 merges HTTP/2 cookie fragments using "; " separators per spec. The attacker exploits HPACK static index 32 (cookie), seeding the dynamic table with an empty cookie value and referencing it thousands of times. Apache accumulates the merge allocation for each reference.

hpack_httpd_cookie_bomb.py — Apache PoC
def build_httpd_cookie_bomb(authority, path, refs):
block = bytearray()
block += indexed(2)    # :method GET
block += indexed(7)    # :scheme https
block += literal_indexed_name_without_indexing(4, path.encode())
block += literal_indexed_name_without_indexing(1, authority.encode())
# Static index 32 = "cookie"
# Empty value → 38-byte dynamic table entry at index 62
# Apache merges cookie crumbs with "; " separator on each ref
block += literal_indexed_name_with_indexing(32, b"")  # seed the table
block += indexed(62) * refs         # 4,091 refs = ~16 MB/stream = 4,000:1
return bytes(block)
Critical Finding

The cookie technique reveals a broader bypass class: splitting Cookie headers into multiple segments tricks servers that enforce only a size limit but not a field count limit. A 1-byte name + 0-byte value slips under any size threshold while still consuming a full field allocation on every reference.

Amplification by Server

Server Version Tested Amplification Time to Exhaust 32 GB Patch Status
Envoy 1.37.2 5,700:1 ~10 seconds Unpatched
Apache HTTPD 2.4.67 4,000:1 ~18 seconds mod_http2 v2.0.41+
NGINX 1.29.7 70:1 ~45 seconds v1.29.8+
Microsoft IIS Windows Server 2025 68:1 ~45s (64 GB RAM) Unpatched
Cloudflare Pingora 0.8.0 ~62:1 Unpatched
CDN Warning

CDN fronting provides partial protection — but only if the CDN layer itself is not Cloudflare Pingora, which is also affected. Do not rely on CDN fronting alone as a mitigation.

Real-World Impact

A Shodan scan at time of disclosure confirmed over 880,000 public-facing servers running one of the affected stacks with HTTP/2 enabled in default configuration. The attack requires no credentials, no recon, and no prior knowledge of the target.

ATTACK REQUIREMENTS vs IMPACT
$0
Cost to Execute
0
Auth Required
32 GB
RAM Consumed (Envoy)
3
Unpatched Servers (of 5)

Patch and Mitigation

NGINX — Patch Available

Upgrade to NGINX 1.29.8+. This release introduces the max_headers directive with a default ceiling of 1,000 header fields per request.

nginx.conf
http {
max_headers 1000;  # default in 1.29.8+
}
# Or disable HTTP/2 entirely:
server {
listen 443 ssl;  # remove 'http2' keyword
}

Apache HTTPD — Patch Available

Update mod_http2 to v2.0.41+. Cookie fragments now count against LimitRequestFields.

httpd.conf
LimitRequestFields 100  # default — ensure this has not been raised
# Disable HTTP/2 if patch unavailable:
Protocols http/1.1

IIS, Envoy, Cloudflare Pingora — No Patch Available

Interim Mitigations

Disable HTTP/2 entirely — Most impactful single mitigation. Eliminates the attack surface completely until a patch is available.
Place patched NGINX 1.29.8+ upstream — Use as a reverse proxy enforcing max_headers 1000 before traffic reaches the vulnerable server.
Apply per-worker memory limits — Use cgroups or container resource constraints to cap worker process memory and limit blast radius.
Monitor vendor advisories — Track patch releases for Microsoft IIS, Envoy, and Cloudflare Pingora. Apply immediately on release.

The AI Angle

The HTTP/2 Bomb was not found by a human researcher. It was discovered by OpenAI Codex, which recognized that two independently published, decade-old techniques could be chained into a combined exploit. Both the discovery and the proof-of-concept code were produced by Codex. Calif preserved the scripts unedited.

"AI-generated and kept as-is, as a historical artifact of what AI vulnerability research looked like in 2026." — Calif repository README
Broader Implication

This is the first publicly documented case of an AI chaining known techniques into a novel critical vulnerability and writing functional exploit code. There are almost certainly other such combinations waiting to be discovered across the CVE corpus and security literature. The threat model for defenders has changed: adversaries now have access to tools that can exhaust the composition space of known techniques at scale.

Detection and Hunting

Behavioral Detection Opportunities

Worker memory spike without traffic spike — RAM grows rapidly while inbound bandwidth stays low. A 70:1+ ratio of memory growth to inbound bytes is anomalous.
HTTP/2 streams with no response data — Streams held open with zero bytes sent from server side despite client sending WINDOW_UPDATE frames.
Repeated 1-byte WINDOW_UPDATE frames — Alert on connections sending increment=1 updates at regular intervals (~50s) with no corresponding data transfer.
OOM killer events on web worker processes — Correlate with concurrent active HTTP/2 connections from a single or small number of source IPs.
Rate limit HTTP/2 connections per IP — A single IP opening 15+ concurrent H2 connections is anomalous for legitimate traffic. Alert or block at the load balancer layer.

MITRE ATT&CK Mapping

Technique Name Implementation
T1499 Endpoint Denial of Service Memory exhaustion via HTTP/2 header bomb
T1499.001 OS/Kernel Exhaustion Flood Worker process OOM via ngx_table_elt_t allocation chain
T1499.002 Service Exhaustion Flood Flow control stall keeps connections open indefinitely
T1071.001 Application Layer Protocol: Web Attack delivered entirely over standard HTTPS/HTTP2
T1190 Exploit Public-Facing Application Default configuration exploitation, no authentication required

References

  1. CVE-2026-49975 — NIST National Vulnerability Database — https://nvd.nist.gov/vuln/detail/CVE-2026-49975
TechOwl SHIELD
Continuous Threat Intelligence & Attack Surface Monitoring

Vulnerability Assessment

Deep technical analysis of vulnerabilities affecting your infrastructure — beyond CVSS scores to real-world exploitability and impact.

Attack Surface Intelligence

Passive mapping of your external presence — every exposed service, endpoint, and piece of infrastructure visible to the public internet.

Threat Hunting

Proactive detection of compromise indicators, APT activity, and post-exploitation artifacts across your email and identity infrastructure.

Dark Web Monitoring

Continuous surveillance of stolen credential markets, threat actor forums, and data leak channels. Know when you're being targeted before it becomes an incident.

© 2026 TechOwl SHIELD. All rights reserved.