Quadratic bignum parsing of Content-Length and Host port values in Bandit
## Summary Inefficient Algorithmic Complexity vulnerability in the header integer parser of mtrudel bandit allows an unauthenticated remote attacker to consume server CPU via a `content-length` value or a `Host` or `:authority` port made of thousands of digits. `Bandit.Headers.parse_integer/2` in `lib/bandit/headers.ex` builds the number one digit at a time with no limit on the digit count, allocating a new bignum at each step, so one value costs time quadratic in its length. It runs on raw request input over HTTP/1 and HTTP/2, before any range check. Over HTTP/2, a 4,000-digit value can be stored once in the HPACK dynamic table and re-sent on each new stream for about one byte: 124 KB of traffic kept the server busy for 27.9 s. This issue affects bandit: from 1.0.0-pre.7 before 1.14.0. ## Details **1. Unbounded digit loop.** `Bandit.Headers.parse_integer/2` in `lib/bandit/headers.ex` builds the number with `total * 10 + digit - ?0` and has no limit on the digit count. Each step allocates a new bignum, so parsing one value costs O(n²). On OTP 28, 10,000 digits take about 10 ms, 50,000 about 250 ms and 80,000 about 560 ms, where `String.to_integer/1` handles the same inputs in 1 to 3 ms. **2. Reached on raw input.** It is called from `get_content_length/1` and `parse_hostlike_header!/1` on raw request input, before any range check. An all-digit `content-length` is returned as `{:ok, huge_int}`, and the `is_port_number` guard only runs after the whole number is built. **3. HPACK amplification.** Over HTTP/2, a 4,000-digit value (about 1.1 ms to parse) can be stored once in the HPACK dynamic table and then re-sent on each new stream for about one byte. ## Proof of concept 1. Run Bandit with any Plug. 2. Open an HTTP/2 connection with prior knowledge and complete the SETTINGS exchange. 3. In one write, send 5,000 HEADERS frames for `POST /` on new streams, each carrying a `content-length` of 4,000 `9` digits encoded with HPACK indexing, so that every frame after the first refers to the stored value. 4. The 124,003 bytes take 27.9 s to process before all 5,000 requests reach the Plug. ## Impact An unauthenticated client can make the server spend CPU time out of all proportion to the traffic it sends (27.9 s for 124 KB in the reporter's test). This affects any Bandit server reachable by untrusted clients over HTTP/1 or HTTP/2, with no special configuration.
describes (1)
Related CVEs.
| ID | severity | exploitable | ||
|---|---|---|---|---|
| CVE-2026-113436US | — | — | ||
Inefficient Algorithmic Complexity vulnerability in the header integer parser of mtrudel bandit allows an unauthenticated remote attacker to consume server CPU via a content-length… | ||||
references
External citations — patches, advisories, analysis.
- https://cna.erlef.org/cves/CVE-2026-113436.htmlWEB
- https://github.com/mtrudel/bandit/commit/220b9dfd27f9a21305be2afc75cbe585ddc24e7aFIX
- https://github.com/mtrudel/bandit/commit/e0c8c0c30af9b0f57d8aafac37ddd9294363a8beWEB
- https://github.com/mtrudel/bandit/security/advisories/GHSA-29cr-8477-rg6rADVISORY
- https://hex.pm/packages/banditPACKAGE
Advisories like this name the exposed products attackers go after on your perimeter. See what is exposed on your perimeter with a free passive scan.
Free scan