Skip to content

xero/hbomb-slowloris-poc-lab

Repository files navigation

HTTP/2 Slowloris Bomb Test Lab for OpenResty

The recent http2-bomb paper shows the attack leveraged against nginx, which got me curious if OpenResty was also vulnerable to the same class of attacks, and what mitigations can be put into place. This repo is a POC and testlab for that work.

Note

This is a self-contained lab that reproduces the HTTP/2 Bomb (hpack indexed-reference bomb + a slowloris window stall) against a sidecar's config, then proves the mitigations work. Everything runs locally against a throwaway container. Never point the bomb at infrastructure you do not own and I take no liability for this software's {mis,}use.


Table of Contents


What this tests

The bomb seeds one HPACK dynamic-table entry (a: with an empty value) and then sends thousands of one-byte indexed references to it. Each one-byte reference forces the server to allocate a fresh header (~59 bytes of pool memory). A SETTINGS_INITIAL_WINDOW_SIZE=0 plus periodic one-byte WINDOW_UPDATE drips keep the response from ever finishing, pinning every allocation in memory. See RFC 7541 §7.3, Memory Consumption for the threat the spec acknowledged and underspecified.

The lab models many production sidecar's decisive knob, large_client_header_buffers 32 32k, which sets the HTTP/2 per-stream header budget to 1 MB instead of the nginx default of 32 KB. That single setting makes the per-stream blast radius about 32 times larger than the values in the research paper.


Requirements

  • Docker running.
  • Host Python 3 (standard library only; the bomb has no dependencies).
  • The lab binds host port 8443 by default. Override with PORT.

Quick start

./run.sh build               # build the OpenResty test image
./run.sh start vuln          # start with the prod-mirroring config (4 GB cap)
./run.sh alpn                # confirm the sidecar negotiates h2
./run.sh version             # confirm the nginx core version (max_headers check)

# in a second terminal, watch the worker
./run.sh monitor

# fire the bomb that fills the 1 MB budget
./run.sh attack-prod

Then A/B the mitigations:

./run.sh start hardened      # 4 32k buffers, 32 streams, 10s timeout, limit_conn
./run.sh attack-prod         # same bomb, watch RSS stay flat

./run.sh start h2off         # http2 disabled
./run.sh attack-prod         # client cannot even negotiate h2

./run.sh with no argument prints the full command list.


The three configs

nginx.vuln.conf. Mirrors many production sidecar's HTTP/2-relevant settings, including large_client_header_buffers 32 32k. This is the baseline.

nginx.hardened.conf. Keeps size at 32k so long request lines and presigned URLs still fit, but cuts number to 4, so the budget drops to 128 KB. Adds http2_max_concurrent_streams 32, send_timeout 10s, and a per-IP limit_conn.

nginx.h2off.conf. Drops the http2 directive entirely. HPACK has no surface, so the bomb cannot run. This is the complete mitigation until OpenResty ships the max_headers directive from nginx 1.29.8.


Measured results

One connection, 16 streams, 1,000,000 references per stream, about 15 MB on the wire. The container core is OpenResty 1.29.2.5 (nginx 1.29.2), capped at 4 GB.

Config header_limit Peak worker RSS Outcome
vuln 1 MB 1,287 MB Memory pinned for the hold; about 84:1 amplification
hardened 128 KB 13 MB Connection killed on the first oversized header block
http2 off n/a 11 MB ALPN refuses h2; client gets NO_APPLICATION_PROTOCOL

The vuln number is from only 16 streams. Many production defaults are 128 concurrent streams per connection, so a single connection scales to roughly 10 GB.


Files

File Purpose
Dockerfile OpenResty alpine plus a self-signed cert and monitoring tools
nginx.vuln.conf Prod-mirroring config (vulnerable)
nginx.hardened.conf Hardened config (mitigations applied)
nginx.h2off.conf HTTP/2 disabled (complete mitigation)
hpack_bomb.py The PoC client, adapted to fill the 1 MB budget
monitor_rss.py In-container per-worker RSS sampler
run.sh Build, start, attack, and observe wrapper

About

POC and self-contained lab that reproduces the HTTP/2 Bomb (hpack indexed-reference bomb + slowloris window stall)

Topics

Resources

Stars

Watchers

Forks

Contributors