May 7, 2026·6 min read·2 visits
Unauthenticated remote attackers can trigger Denial of Service in the Bandit Elixir HTTP server via memory exhaustion by sending oversized HTTP/2 frames, bypassing size limits due to deferred buffer validation in pattern matching.
CVE-2026-42788 is a critical resource management vulnerability in the Bandit HTTP server for Elixir. The flaw exists within the HTTP/2 frame deserialization logic, where binary pattern matching defers size validation until after memory allocation. This allows an unauthenticated remote attacker to cause memory exhaustion and Denial of Service by transmitting oversized HTTP/2 frames.
Bandit is a high-performance HTTP server designed for the Elixir ecosystem. It handles HTTP/1.x, HTTP/2, and WebSocket connections, relying on the Erlang BEAM virtual machine for concurrent request processing. The server exposes network endpoints directly to clients, making it a critical component of the application's attack surface.
The vulnerability, classified as CWE-770 (Allocation of Resources Without Limits or Throttling), resides in the lib/bandit/http2/frame.ex module. This module manages the parsing and deserialization of incoming HTTP/2 frames from client connections. A flaw in how frame payloads are evaluated allows attackers to bypass protocol limits.
While this vulnerability does not permit remote code execution or data exfiltration, the impact on availability is significant. An attacker can force the server process to consume memory unbounded by protocol negotiation, ultimately resulting in memory exhaustion and a complete Denial of Service for the affected BEAM node.
The root cause of CVE-2026-42788 stems from Elixir's binary pattern matching mechanics and the specific implementation of the 'Elixir.Bandit.HTTP2.Frame':deserialize/2 function. The original code utilized a pattern match that parsed the entire HTTP/2 frame, including its payload, before evaluating security guards.
HTTP/2 frames begin with a 9-byte header that includes a 24-bit length field, dictating the size of the subsequent payload. This length field can announce a size up to approximately 16 MiB. In the vulnerable function, the clause payload::binary-size(length) instructed the BEAM VM to buffer the exact number of bytes specified by the header before successful pattern matching could occur.
The security guard when length > max_frame_size was placed on the function signature but was strictly evaluated only after the pattern match completed. This architectural sequence forced the server to continue reading from the socket until the full, untrusted length was buffered in memory.
Consequently, the server failed to enforce the negotiated max_frame_size (typically 16 KiB per RFC 9113) early in the parsing phase. The server process allocated memory up to the 16 MiB theoretical limit per frame, deferring rejection until the excessive allocation had already taken place.
The vulnerability is evident when examining the pre-patch frame deserialization logic. The implementation attempted to parse the header and the full payload simultaneously. The function definition appeared as follows:
def deserialize(
<<length::24, type::8, flags::8, _reserved::1, stream_id::31,
payload::binary-size(length), rest::binary>>,
max_frame_size
)
when length > max_frame_size do
# ...If an attacker submitted an announced length of 16777215 (16 MiB), the payload::binary-size(length) clause forced the Bandit server to return {:more, msg}. The connection handler continuously read and buffered network data until 16 MiB accumulated, only to subsequently reject it based on the guard clause.
Commit 1e8e55966da9129016b73d32f0e1df4630e3b463 resolves the defect by introducing an early-check clause that processes only the 9-byte header. The patched code is structured as follows:
# New "early-check" clause
def deserialize(
<<length::24, _type::8, _flags::8, _reserved::1, _stream_id::31, rest::binary>>,
max_frame_size
)
when length > max_frame_size do
{{:error, Bandit.HTTP2.Errors.frame_size_error(), "Payload size too large (RFC9113§4.2)"},
rest}
endThis short-circuit clause matches the header without evaluating the payload block. Because Elixir evaluates function clauses sequentially, the VM immediately checks length > max_frame_size upon receiving the first 9 bytes. If the declared size exceeds limits, the server instantly throws a frame_size_error and terminates the stream, precluding any memory allocation for the payload.
Exploitation of CVE-2026-42788 requires standard network access to the port hosting the Bandit HTTP/2 service. The attack does not require authentication, specific user privileges, or complex state manipulation. The methodology is reliable and predictable across default installations.
The attacker initiates standard HTTP/2 handshakes across multiple concurrent connections. During negotiation, the server and client agree upon a standard max_frame_size, typically 16 KiB. The attacker then transmits crafted HTTP/2 frame headers declaring a payload length of 16 MiB (length = 16777215) for each connection, but deliberately withholds the actual payload data.
The vulnerable server begins buffering data for each stream, holding the connections open in an active read state. By establishing hundreds of parallel connections and sending these crafted 9-byte headers, the attacker orchestrates a concurrent memory allocation spike. For 1,000 connections, the server attempts to buffer up to 16 GiB of memory.
The BEAM VM attempts to honor these allocations, leading to rapid memory exhaustion. The operating system's OOM killer will eventually terminate the BEAM process, or the node will crash due to allocation failures, resulting in a successful Denial of Service.
The definitive impact of this vulnerability is a targeted Denial of Service against the server component. Unauthenticated attackers can crash the host application efficiently, necessitating minimal bandwidth and computational resources from the attacking system.
The vulnerability is scored as CVSS 6.9 (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N). The lack of complexity, requirement for user interaction, and necessity for privileges drive the score. The impact is strictly confined to the availability of the vulnerable component.
Currently, the EPSS score sits at 0.00017 (4.00th percentile). This indicates an extremely low probability of active exploitation in the wild. Threat intelligence platforms and public repositories show no weaponized proof-of-concept exploits circulating for this specific CVE.
Operational impact depends on the deployment architecture. Single-node deployments without resource constraints face complete service disruption. Orchestrated environments (like Kubernetes) will observe container restarts and potential crash loop backoff, disrupting service availability but maintaining underlying host stability.
The authoritative remediation strategy is upgrading the bandit dependency to version 1.11.0. This release contains the complete patch addressing the deserialization logic. Development teams must update their mix.exs configurations and generate a new mix.lock file to incorporate the fixed library.
Operators can confirm the active version by inspecting the resolved dependencies in their project structure. Running grep "bandit" mix.lock within the application repository verifies whether the deployed version is below the 1.11.0 threshold.
If immediate patching is unfeasible, reverse proxies or Web Application Firewalls (WAF) can provide interim protection. Configuring strict connection limits and concurrency thresholds at the Nginx or HAProxy layer restricts the number of simultaneous streams an attacker can utilize, mitigating the memory exhaustion attack vector.
Additionally, infrastructure teams should enforce robust process-level resource limits. Implementing memory constraints via cgroups or container orchestration policies ensures that a single vulnerable application cannot monopolize host memory and compromise co-located services.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
bandit mtrudel | 0.3.6 <= version < 1.11.0 | 1.11.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 |
| Attack Vector | Network |
| CVSS v4.0 | 6.9 |
| EPSS Score | 0.00017 |
| Impact | Denial of Service (DoS) |
| Exploit Status | None |
| CISA KEV | Not Listed |
Allocation of Resources Without Limits or Throttling