eef-cve-2026-113436

CVSS 8.7 osv_hex
Description

## 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.

Timeline
Published
unknown
Last Modified
unknown
CVSS Details

CVSS details not available.

Affected Products

No product information available.

Weaknesses (CWE)
References
Linked Vulnerabilities

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"
}
View JSON API Download JSON