Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessOpen HTTP/2 connection unauthenticated
-
DeliverySend one TCP write with N+1 HEADERS frames
-
ExploitFinal frame raises StreamError, limits roll back
-
ExecutionEarlier streams keep running Plug calls uncounted
-
PersistRepeat writes to accumulate concurrency
-
ImpactExhaust server processes, CPU and memory
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A10:2025 - Mishandling of Exceptional Conditions
ASVS 5.0
V16 - Security Logging and Error Handling Exception cleanup procedures
|
| Exploitation Conditions | Exploitation requires that the target run Bandit (1.9.0 up to but not including 1.14.0) serving HTTP/2 with a finite max_concurrent_streams - HTTP/2 is served by default on Bandit's HTTPS/h2 listeners and max_concurrent_streams has a default value, so default HTTP/2 deployments are exploitable without special configuration. The attacker must craft a single TCP write carrying multiple HEADERS frames where at least one frame raises a StreamError (per the advisory, a header block encoded without indexing), which causes handle_data/3 to roll back connection state. No authentication, user interaction, or local access is needed (PR:N/UI:N). The principal limiting factor is that only the HTTP/2 handler is affected: deployments that disable HTTP/2 (http_2_options: [enabled: false]) are not exploitable, and HTTP/1-only listeners are unaffected. Impact is confined to availability (process/CPU/memory exhaustion); no data confidentiality or integrity is at stake. |
| Impact | This is a genuine but bounded availability issue rather than a top-tier emergency. The supplied CVSS 4.0 vector (AV:N/AC:L/AT:P/PR:N/UI:N) and score of 8.2 reflect a network-reachable, unauthenticated flaw whose only impact is availability (VA:H; VC:N/VI:N), which matches the described mechanism: an attacker bypasses the per-connection max_concurrent_streams / max_requests / rapid-reset limits and runs far more concurrent Plug calls than configured, exhausting processes, CPU and memory. The priority signal is 'this_week' (vuln.today), consistent with a serious DoS-class bug that is not under active exploitation. There is NO CISA KEV listing and NO EPSS score in the provided data, so widespread automated exploitation is not evidenced - this points to a defensible-but-not-firefight posture. A detailed proof-of-concept is published in the GHSA advisory (deterministic steps: configure max_concurrent_streams, send 11 HEADERS frames per TCP write, repeat), which lowers the practical barrier to exploitation. One caveat to flag explicitly: the input tag 'Authentication Bypass' conflicts with the actual mechanism - the CVSS shows PR:N and VC:N/VI:N, and the advisory describes a resource-limit bypass, not any authentication bypass, so that tag is misleading. Overall: real priority for Elixir/Phoenix shops running HTTP/2, but severity rests entirely on availability, not data compromise. |
| Exploit ScenarioDerived | An unauthenticated remote attacker opens an HTTP/2 connection to a Bandit server and sends a single TCP write containing several HEADERS frames where the last one triggers a StreamError; the server refuses the final stream but forgets the earlier ones, so their Plug calls keep running while the connection's limit bookkeeping rolls back. By repeating this write the attacker accumulates many more concurrent requests than max_concurrent_streams permits on one connection, exhausting server processes, CPU and memory. A public PoC reference exists in the vendor advisory describing the exact frame sequence; it is not verified as working exploit code in the provided data. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 26, 2026
HTTP/2 resource-limit bypass in the Elixir Bandit web server (1.9.0 through 1.13.x) lets an unauthenticated remote client exceed the configured max_concurrent_streams and max_requests caps by packing multiple HEADERS frames into a single TCP write where one frame raises a StreamError, causing the handler to continue from pre-chunk connection state. Because stream counts, last_stream_id, rapid-reset timestamps and the HPACK decoder state are all rolled back while the already-started Plug calls keep running, an attacker can drive roughly five times the intended number of concurrent Plug invocations per connection (50 running against a limit of 10 in the reporter's test), exhausting server processes, CPU and memory. Impact is strictly availability - no confidentiality or integrity loss - HTTP/2 with a finite max_concurrent_streams is the default for Bandit's TLS/h2 listeners, no public exploit code is confirmed, and a vendor patch is available.
RemediationAI
Vendor-released patch: upgrade Bandit to 1.14.0 or later, which is the first version containing the fix from commit 220b9dfd27f9a21305be2afc75cbe585ddc24e7a; details are in advisory GHSA-2238-pgfc-w82m (https://github.com/mtrudel/bandit/security/advisories/GHSA-2238-pgfc-w82m), with cross-references at https://osv.dev/vulnerability/EEF-CVE-2026-111103 and https://cna.erlef.org/cves/CVE-2026-111103.html. If an immediate upgrade is not possible, the vendor-documented workaround is to disable HTTP/2 entirely with http_2_options: [enabled: false], which prevents the vulnerable handler from running at all; the trade-off is loss of HTTP/2 multiplexing and its performance benefits for all clients on that listener. Because the issue is an availability-only resource-cap bypass, limiting exposure at the network layer to trusted clients until the upgrade can be completed reduces the pool of potential abusers.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Bandit is an HTTP server written in Elixir and built on Thousand Island and Ranch, and this flaw lives in its HTTP/2 codec layer (lib/bandit/http2/handler.ex and connection.ex), a class CWE-460 improper cleanup on thrown exception. In handle_data/3, frames are deserialized from a TCP chunk inside an Enum.reduce_while/3 that is wrapped in a function-level rescue; when Bandit.HTTP2.Connection.handle_frame/3 raises StreamError partway through the chunk, rescue_stream_error/3 sends RST_STREAM and returns {:continue, state} using the original function argument rather than the reduce accumulator. All bookkeeping mutated by the earlier frames - stream counts, last_stream_id, reset_stream_timestamps, recv_hpack_state and the receive buffer - reverts to its pre-chunk value, while the stream processes for those frames continue executing their Plug calls untouched. The same rollback also discards HPACK dynamic-table updates, which the advisory notes can mix up headers between requests, misalign subsequent frame parsing, and emit a stale last_stream_id in GOAWAY. The upstream fix (commit 220b9df and its introducing-side context in 3ad49c8) introduces a new_stream!/2 helper that checks the max_requests cap and compares local_settings.max_concurrent_streams against a new StreamCollection.open_stream_count/1 before a stream is registered, raising a proper stream-scoped error, and separates rescue_stream_error from rescue_connection_error so connection state is no longer rewound.
Know when Bandit gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Remote, unauthenticated, deterministic single-write trigger gives AV:N/AC:L/PR:N/UI:N; impact is unbounded per-connection resource exhaustion (A:H) with no confidentiality or integrity effect.
Primary rating from Vendor (EEF).
CVSS VectorVendor: EEF
DescriptionCVE.org
Improper Cleanup on Thrown Exception vulnerability in the HTTP/2 handler of mtrudel bandit allows an unauthenticated remote attacker to bypass per-connection resource limits via a single TCP write that carries several frames, one of which raises a stream error.
When a frame raises StreamError partway through a chunk, Bandit.HTTP2.Handler.handle_data/3 sends RST_STREAM and continues with the connection state from before the chunk, dropping the rest of it. Streams opened by earlier frames in the chunk keep running their Plug calls, but the stream counts, last_stream_id, the rapid-reset timestamps, the HPACK decoder state and the buffer roll back, so max_concurrent_streams, max_requests and the rapid-reset limiter never see those streams. A client that sends one HEADERS frame more than max_concurrent_streams in each write has the extra refused and the others forgotten: with a limit of 10, five such writes run 50 Plug calls at once.
This issue affects bandit: from 1.9.0 before 1.14.0.
Technical POC Analysis
CWE-460 (Improper Cleanup on Thrown Exception).
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Executive ViewAI
A high-severity flaw in the Elixir Bandit web server allows unauthenticated remote attackers to bypass HTTP/2 concurrency limits, potentially overwhelming server resources and causing denial-of-service. Organizations using Bandit versions 1.9.0 through 1.13.x for TLS or HTTP/2 listeners are at risk, with default configurations vulnerable. Leadership should prioritize patching to maintain service availability and prevent disruptive outages.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Memory exhaustion in Bandit WebSocket server (versions 0.5.0 through 1.10.x) allows unauthenticated remote attackers to
Memory exhaustion in Bandit WebSocket server (versions 0.5.9 through 1.10.x) allows unauthenticated remote attackers to
Denial of service in mtrudel bandit via HTTP/2 frame deserialization allows unauthenticated remote attackers to exhaust
Transport-state spoofing in Bandit 1.0.0 through 1.10.x allows unauthenticated remote attackers to forge HTTPS connectio
HTTP request smuggling in mtrudel bandit before version 1.11.0 allows unauthenticated attackers to bypass edge security
Uncontrolled HTTP/2 flow-control resource consumption in mtrudel/bandit 1.4.0 and later lets an unauthenticated remote p
Unauthenticated remote denial of service in mtrudel Bandit (Elixir HTTP server) versions 1.6.1 through 1.11.0 lets any c
CPU exhaustion in bandit 1.11.0 to 1.12.0 allows unauthenticated remote denial-of-service via WebSocket fragment reassem
Unauthenticated remote denial of service in Bandit (the Elixir HTTP/1 web server for Phoenix/Plug applications) versions
Bandit's HTTP/2 request body reader amplifies memory use, letting an unauthenticated remote client make a server hold ro
Unauthenticated remote CPU exhaustion in mtrudel Bandit's HTTP/2 server (versions before 1.14.0) is achievable by holdin
Unbounded per-connection memory and CPU growth in the Elixir Bandit HTTP/2 server (0.3.6 up to 1.14.0) lets an unauthent
EUVD-2026-109825
NVD
CVE.org
EPSS
Vulnrichment
GitHub
Exploit-DB