eef-cve-2026-113436
CVSS 8.7 osv_hex## 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.
- Published
- unknown
- Last Modified
- unknown
CVSS details not available.
No product information available.
- https://github.com/mtrudel/bandit/security/advisories/GHSA-29cr-8477-rg6r
- https://cna.erlef.org/cves/CVE-2026-113436.html
- https://github.com/mtrudel/bandit/commit/e0c8c0c30af9b0f57d8aafac37ddd9294363a8be
- https://github.com/mtrudel/bandit/commit/220b9dfd27f9a21305be2afc75cbe585ddc24e7a
- https://hex.pm/packages/bandit
No linked vulnerabilities found.
{
"affected": [
{
"database_specific": {
"source": "https://cna.erlef.org/osv/EEF-CVE-2026-113436.json"
},
"package": {
"ecosystem": "Hex",
"name": "bandit",
"purl": "pkg:hex/bandit"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0-pre.7"
},
{
"fixed": "1.14.0"
}
],
"type": "SEMVER"
}
],
"versions": [
"1.0.0",
"1.0.0-pre.10",
"1.0.0-pre.11",
"1.0.0-pre.12",
"1.0.0-pre.13",
"1.0.0-pre.14",
"1.0.0-pre.15",
"1.0.0-pre.16",
"1.0.0-pre.17",
"1.0.0-pre.18",
"1.0.0-pre.7",
"1.0.0-pre.8",
"1.0.0-pre.9",
"1.1.0",
"1.1.1",
"1.1.2",
"1.1.3",
"1.10.0",
"1.10.1",
"1.10.2",
"1.10.3",
"1.10.4",
"1.11.0",
"1.11.1",
"1.12.0",
"1.12.1",
"1.12.2",
"1.12.3",
"1.12.4",
"1.12.5",
"1.13.0",
"1.13.1",
"1.2.0",
"1.2.1",
"1.2.2",
"1.2.3",
"1.3.0",
"1.4.0",
"1.4.1",
"1.4.2",
"1.5.0",
"1.5.1",
"1.5.2",
"1.5.3",
"1.5.4",
"1.5.5",
"1.5.6",
"1.5.7",
"1.6.0",
"1.6.1",
"1.6.10",
"1.6.11",
"1.6.2",
"1.6.3",
"1.6.4",
"1.6.5",
"1.6.6",
"1.6.7",
"1.6.8",
"1.6.9",
"1.7.0",
"1.8.0",
"1.9.0"
]
},
{
"database_specific": {
"source": "https://cna.erlef.org/osv/EEF-CVE-2026-113436.json"
},
"ranges": [
{
"events": [
{
"introduced": "e0c8c0c30af9b0f57d8aafac37ddd9294363a8be"
},
{
"fixed": "220b9dfd27f9a21305be2afc75cbe585ddc24e7a"
}
],
"repo": "https://github.com/mtrudel/bandit",
"type": "GIT"
}
],
"versions": [
"1.13.1",
"1.13.0",
"1.12.5",
"1.12.4",
"1.12.3",
"1.12.1",
"1.12.0",
"1.11.1",
"1.11.0",
"1.10.4",
"1.10.3",
"1.10.2",
"1.10.1",
"1.10.0",
"1.9.0",
"1.8.0",
"1.7.0",
"1.6.11",
"1.6.10",
"1.6.9",
"1.6.8",
"1.6.7",
"1.6.6",
"1.6.5",
"1.6.4",
"1.6.3",
"1.6.2",
"1.6.1",
"1.6.0",
"1.5.7",
"1.5.6",
"1.5.5",
"1.5.4",
"1.5.3",
"1.5.2",
"1.5.1",
"1.5.0",
"1.4.2",
"1.4.1",
"1.4.0",
"1.3.0",
"1.2.3",
"1.2.0",
"1.1.3",
"1.1.2",
"1.1.1",
"1.1.0",
"1.0.0",
"1.0.0-pre.18",
"1.0.0-pre.17",
"1.0.0-pre.16",
"1.0.0-pre.15",
"1.0.0-pre.14",
"1.0.0-pre.13",
"1.0.0-pre.12",
"1.0.0-pre.11",
"1.0.0-pre.10",
"1.0.0-pre.9",
"1.0.0-pre.8",
"1.0.0-pre.7"
]
}
],
"aliases": [
"CVE-2026-113436",
"GHSA-29cr-8477-rg6r"
],
"credits": [
{
"name": "Peter Ullrich",
"type": "REPORTER"
},
{
"name": "Mat Trudel",
"type": "REMEDIATION_DEVELOPER"
},
{
"name": "Jonatan Männchen / EEF",
"type": "ANALYST"
}
],
"database_specific": {
"capec_ids": [
"CAPEC-130"
],
"cpe_ids": [
"cpe:2.3:a:mtrudel:bandit:*:*:*:*:*:*:*:*"
],
"cwe_ids": [
"CWE-407"
]
},
"details": "## Summary\n\nInefficient 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.\n\n`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.\n\nThis issue affects bandit: from 1.0.0-pre.7 before 1.14.0.\n\n## Details\n\n**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.\n\n**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.\n\n**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.\n\n## Proof of concept\n\n1. Run Bandit with any Plug.\n2. Open an HTTP/2 connection with prior knowledge and complete the SETTINGS exchange.\n3. 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.\n4. The 124,003 bytes take 27.9 s to process before all 5,000 requests reach the Plug.\n\n## Impact\n\nAn 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.",
"id": "EEF-CVE-2026-113436",
"modified": "2026-10-26T13:56:06.731234193Z",
"published": "2026-10-26T13:31:35.033Z",
"references": [
{
"type": "ADVISORY",
"url": "https://github.com/mtrudel/bandit/security/advisories/GHSA-29cr-8477-rg6r"
},
{
"type": "WEB",
"url": "https://cna.erlef.org/cves/CVE-2026-113436.html"
},
{
"type": "WEB",
"url": "https://github.com/mtrudel/bandit/commit/e0c8c0c30af9b0f57d8aafac37ddd9294363a8be"
},
{
"type": "FIX",
"url": "https://github.com/mtrudel/bandit/commit/220b9dfd27f9a21305be2afc75cbe585ddc24e7a"
},
{
"type": "PACKAGE",
"url": "https://hex.pm/packages/bandit"
}
],
"schema_version": "1.9.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Quadratic bignum parsing of Content-Length and Host port values in Bandit"
}