Skip to main content

Bandit CVE-2026-39803

| EUVDEUVD-2026-29950 HIGH
Allocation of Resources Without Limits or Throttling (CWE-770)
2026-05-13 EEF GHSA-9q9q-324x-93r2
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

Remote, unauthenticated, single-request trigger with no user interaction (AV:N/AC:L/PR:N/UI:N); impact is availability-only (A:H, C:N/I:N) with no scope change.

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:56 vuln.today
Analysis Generated
Jul 23, 2026 - 18:56 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

Allocation of Resources Without Limits or Throttling vulnerability in mtrudel bandit allows unauthenticated remote denial of service via memory exhaustion.

The chunked clause of 'Elixir.Bandit.HTTP1.Socket':read_data/2 in lib/bandit/http1/socket.ex ignores the caller-supplied :length option when reading HTTP/1 chunked request bodies. Instead of capping the accumulated body at the configured limit (e.g. Plug.Parsers' default 8 MB), do_read_chunked_data!/5 buffers every received chunk into an iolist unconditionally and materializes the entire body as a single binary. The function always returns {:ok, body, ...}, so callers cannot interpose a 413 response.

Because Plug.Parsers runs before routing and authentication in the standard Phoenix endpoint, an unauthenticated attacker needs no valid route or credentials. Sending a single Transfer-Encoding: chunked POST request with an arbitrarily large body to any path causes the BEAM process to exhaust available memory and be terminated by the OS OOM killer.

The content-length path in the same function correctly enforces the limit and is not affected.

This issue affects bandit: from 1.4.0 before 1.11.1.

AnalysisAI

Unauthenticated remote denial of service in Bandit (the Elixir HTTP/1 web server for Phoenix/Plug applications) versions 1.4.0 through 1.11.0 allows an attacker to crash the entire BEAM VM by sending a single Transfer-Encoding: chunked POST with an oversized body. The chunked-body reader ignores the application's configured :length cap (e.g. Plug.Parsers' default 8 MB), buffering the whole body in memory until the OS OOM killer terminates the process. Publicly available exploit code exists (a self-contained PoC ships in the GHSA advisory), though EPSS remains low at 0.31% and it is not listed in CISA KEV.

Technical ContextAI

Bandit is a pure-Elixir HTTP server built on Thousand Island that serves as the Plug/Phoenix web adapter, increasingly the default in modern Phoenix stacks. The root cause is CWE-770 (Allocation of Resources Without Limits or Throttling): in lib/bandit/http1/socket.ex, the chunked clause of read_data/2 forwards only :read_length and :read_timeout to do_read_chunked_data!/5 and drops the caller-supplied :length option. It accumulates every chunk into an iolist and calls IO.iodata_to_binary/1 to materialize the full body, always returning {:ok, body, ...} and never {:more, ...}, so upstream callers (Plug.Parsers) get no chance to emit a 413. By contrast, the Content-Length path correctly bounds reads with min(unread_content_length, Keyword.get(opts, :length, 8_000_000)) and is unaffected. The CPE cpe:2.3:a:mtrudel:bandit identifies the affected package.

RemediationAI

Vendor-released patch: 1.11.1 - upgrade the bandit dependency to 1.11.1 or later (mix deps.update bandit / pin {:bandit, "~> 1.11.1"} in mix.exs), which changes do_read_chunked_data! to track accumulated bytes against the :length option and return {:more, ...} or raise a request_error! once the cap is exceeded (fix commit ae3520dfdbfab115c638f8c7f6f6b805db34e1ab). If you cannot upgrade immediately, place a reverse proxy or load balancer in front of Bandit and enforce a hard request-body size limit there (for example nginx client_max_body_size or an equivalent cap on chunked/streamed bodies) so oversized bodies are rejected before reaching the BEAM - the trade-off is that legitimate large uploads will also be capped and you must ensure the proxy limit is applied to chunked transfers, not just Content-Length requests. As an operational backstop, constrain the BEAM process memory (cgroup/systemd MemoryMax) so an OOM affects only that container rather than the host, accepting that the service still crashes on attack. Advisories: https://github.com/mtrudel/bandit/security/advisories/GHSA-9q9q-324x-93r2 and https://cna.erlef.org/cves/CVE-2026-39803.html.

Share

CVE-2026-39803 vulnerability details – vuln.today

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