Skip to main content

Bandit CVE-2026-39806

| EUVDEUVD-2026-29951 HIGH
Loop with Unreachable Exit Condition (Infinite Loop) (CWE-835)
2026-05-13 EEF GHSA-rf5q-vwxw-gmrf
8.7
CVSS 4.0 · NVD
Share

Severity by source

NVD PRIMARY
8.7 HIGH
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
vuln.today AI
7.5 HIGH

Network-reachable, no auth or interaction, low complexity via a fixed byte sequence; availability-only impact (worker exhaustion) with no confidentiality or integrity effect.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Primary rating from NVD.

CVSS VectorNVD

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
X

Lifecycle Timeline

4
Source Code Evidence Fetched
Jul 23, 2026 - 18:54 vuln.today
Analysis Generated
Jul 23, 2026 - 18:54 vuln.today
CVE Published
May 13, 2026 - 13:36 cve.org
HIGH 8.7
CVE Published
May 13, 2026 - 13:36 nvd
UNKNOWN (no severity yet)

DescriptionCVE.org

Loop with Unreachable Exit Condition ('Infinite Loop') vulnerability in mtrudel bandit allows unauthenticated remote denial of service via worker process exhaustion.

'Elixir.Bandit.HTTP1.Socket':do_read_chunked_data!/5 in lib/bandit/http1/socket.ex terminates only when the last-chunk line 0\r\n is followed immediately by the empty trailer line \r\n. RFC 9112 §7.1.2 permits zero or more trailer fields between them. When trailers are present, none of the match clauses fit: the catch-all arm computes a negative to_read, calls read_available!/2, receives <<>> on timeout, and tail-recurses with unchanged state. The worker process is pinned for the lifetime of the TCP connection.

A handful of concurrent connections sending RFC-conformant chunked requests with trailer fields is sufficient to exhaust the Bandit worker pool and render the server unresponsive to all further traffic. No authentication, special headers, or large payload is required. Proxies such as NGINX and HAProxy legitimately forward trailer-bearing requests, so servers behind such proxies may be affected without any malicious client involvement.

This issue affects bandit: from 1.6.1 before 1.11.1.

AnalysisAI

Unauthenticated remote denial of service in mtrudel Bandit (Elixir HTTP server) versions 1.6.1 through 1.11.0 lets any client pin a worker process indefinitely by sending an RFC 9112-conformant chunked request that ends with trailer fields. Because the HTTP/1 chunked decoder only terminates on a bare '0\r\n\r\n' and never consumes trailers, a handful of concurrent connections exhausts the worker pool and makes the server unresponsive to all traffic. Publicly available exploit code exists (a self-contained PoC ships in the GHSA advisory), though the flaw is not listed in CISA KEV and EPSS is low (0.47%).

Technical ContextAI

Bandit is a pure-Elixir HTTP/1.1 and HTTP/2 web server built on Thousand Island/ranch that commonly backs Phoenix applications as an alternative to Cowboy. The defect is a CWE-835 Loop with Unreachable Exit Condition in lib/bandit/http1/socket.ex, function do_read_chunked_data!/5. Its terminator clause matches only the pattern ['0', '\r\n' <> rest] - the last-chunk marker immediately followed by the empty trailer line. RFC 9112 §7.1.2 permits zero or more trailer fields between the '0\r\n' line and the final '\r\n', so a body ending '0\r\nX-T: v\r\n\r\n' causes :binary.split/2 to return ['0', 'X-T: v\r\n\r\n'], which fails every match clause. Execution falls into the catch-all arm, computes a negative to_read (0 - byte_size(rest)), calls read_available!/2 which returns <<>> on timeout, and tail-recurses with an unchanged buffer - making no forward progress. A source comment on line 245 ('We should be reading (and ignoring) trailers here') acknowledges the gap. The same non-progress shape also triggers on malformed chunk frames whose declared size disagrees with the actual data length.

RemediationAI

Vendor-released patch: upgrade Bandit to 1.11.1 or later, which rewrites the chunked decoder to parse and discard trailers (via do_read_headers! on the trailer section) and guarantees forward progress by raising a request error instead of re-entering with an unchanged buffer; the fix is commit ae3520dfdbfab115c638f8c7f6f6b805db34e1ab, described in advisory https://github.com/mtrudel/bandit/security/advisories/GHSA-rf5q-vwxw-gmrf. If you cannot upgrade immediately, the most direct compensating control is to strip or reject trailer fields at an upstream proxy before requests reach Bandit - for example configure NGINX/HAProxy to not forward chunked trailers, or reject requests whose chunked body contains data after the '0\r\n' last-chunk marker; the trade-off is that legitimate trailer-bearing clients (rare in practice) would break. As secondary controls, place the server behind a WAF or rate limiter that caps concurrent long-lived connections per source and monitor for worker-pool saturation, accepting that these only slow an attacker rather than closing the bug. Because trailers are RFC-legal and can arrive from benign proxied traffic, patching to 1.11.1 is strongly preferred over any filtering workaround.

Share

CVE-2026-39806 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy