CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-42786
8.70.06%

CVE-2026-42786: Unbounded WebSocket Fragmented Message Reassembly Denial of Service in Bandit

Amit Schendel
Amit Schendel
Senior Security Researcher

May 7, 2026·6 min read·3 visits

No Known Exploit

Executive Summary (TL;DR)

Bandit < 1.11.0 fails to limit cumulative size of fragmented WebSocket messages, allowing unauthenticated attackers to cause an Out-of-Memory (OOM) denial of service by sending infinite continuation frames.

An unauthenticated remote denial of service vulnerability exists in the Bandit HTTP server due to unbounded resource allocation during WebSocket fragment reassembly. Attackers can trigger complete memory exhaustion by streaming continuous WebSocket frames without the finalization bit, causing the Erlang virtual machine to crash.

Vulnerability Overview

Bandit is an HTTP server for the Elixir ecosystem, commonly utilized as a high-performance replacement for Cowboy in Phoenix applications. It processes both standard HTTP traffic and persistent protocols such as WebSockets. The server is responsible for parsing protocol frames, managing connection states, and passing reassembled payloads to application-level handlers.

CVE-2026-42786 is a high-severity Denial of Service (DoS) vulnerability categorized under CWE-770 (Allocation of Resources Without Limits or Throttling). It affects Bandit versions 0.5.0 prior to version 1.11.0. The vulnerability is isolated to the WebSocket connection handler, specifically within the logic responsible for reassembling fragmented WebSocket messages.

Unauthenticated attackers exploit this implementation flaw by establishing a WebSocket connection and transmitting an unbounded stream of data payloads. Because the server does not enforce a cumulative size limit on these fragments, the process allocates memory linearly until host resources are completely exhausted. Successful exploitation terminates the Erlang virtual machine (BEAM), resulting in an application-wide denial of service.

Root Cause Analysis

The WebSocket protocol specification (RFC 6455) permits message fragmentation to facilitate the transmission of payloads whose ultimate size is unknown at the origin. A fragmented message sequence begins with an initial frame specifying the data type (Text or Binary), followed by zero or more Continuation frames. The sequence concludes when a frame transmits a fin control bit set to 1.

Bandit implements this fragment reassembly logic within the Bandit.WebSocket.Connection.handle_frame/3 function. Prior to version 1.11.0, this function unconditionally appended the payload of any incoming Continuation{fin: false} frame to an iolist data structure maintained in the connection state. This aggregation occurred entirely at the transport layer, preceding any invocation of application-level handlers like WebSock.handle_in/2.

The server enforced a max_frame_size limit on individual incoming frames. However, the system lacked a constraint mechanism to evaluate or restrict the cumulative size of the entire reassembled message. The iolist structure grew continuously as long as the TCP connection remained open and incoming frames lacked the fin bit, resulting in completely unbounded memory allocation.

Code Analysis

The vulnerable implementation existed in lib/bandit/websocket/connection.ex. The logic intercepted continuation frames with a false fin bit and mutated the connection state by prepending the new frame data to the existing sequence. The code unconditionally executed the memory allocation.

# Vulnerable Implementation
%Frame.Continuation{fin: false} = frame ->
  data = [connection.fragment_frame.data | frame.data]
  frame = %{connection.fragment_frame | fin: true, data: data}
  {:continue, %{connection | fragment_frame: frame}}

The fix introduced in commit 21612c7c7b1ce43eccd36d3af3a2299d23513667 implements a new configuration parameter, max_fragmented_message_size, which defaults to 8,000,000 bytes. The modified logic evaluates the aggregate size using the IO.iodata_length/1 function upon the receipt of every continuation frame.

# Patched Implementation
%Frame.Continuation{fin: false} = frame ->
  data = [connection.fragment_frame.data | frame.data]
  if IO.iodata_length(data) > connection.max_fragmented_message_size do
    {:error, 1009}
  else
    frame = %{connection.fragment_frame | fin: true, data: data}
    {:continue, %{connection | fragment_frame: frame}}
  end

When the cumulative data length exceeds the configured threshold, the server immediately returns {:error, 1009}. This instructs the transport layer to sever the connection with WebSocket status code 1009 (Message Too Big), mitigating the memory exhaustion vector.

Exploitation Methodology

Exploitation requires zero privileges, no authentication, and no user interaction. An attacker requires only standard network access to the target application's WebSocket endpoint. The exploitation technique relies exclusively on valid WebSocket protocol formatting rather than memory corruption or parsing errors.

The adversary initiates a standard WebSocket handshake over an HTTP Upgrade request. Upon establishment, the attacker transmits an initial Text or Binary frame with the fin flag set to 0. This signals to the Bandit server that a fragmented message sequence has commenced, placing the connection handler into the accumulation state.

The attacker then enters an automated loop, transmitting Continuation frames with fin: 0. To maximize resource consumption efficiency, the attacker sizes these individual frames up to the application's max_frame_size parameter. The server buffers all payloads in memory indefinitely, ultimately inducing an Out-of-Memory condition that terminates the application process.

Impact Assessment

The vulnerability strictly impacts system availability. The CVSS 4.0 vector 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 produces a severity score of 8.7, accurately classifying the flaw as a high-severity denial of service condition.

Elixir processes operate within the Erlang Virtual Machine (BEAM). Unbounded memory exhaustion within a single WebSocket connection process initiates aggressive garbage collection cycles. Because the memory is legitimately referenced by the iolist, garbage collection fails to reclaim space. The process continuously expands until it exhausts the physical memory and swap space allocated to the entire VM node.

When the BEAM node exhausts available operating system memory, the kernel OOM killer terminates the primary virtual machine process. This action completely disables the hosted application, abruptly dropping all active connections, invalidating sessions, and destroying transient internal state. Services require a complete restart to restore functionality.

Remediation and Variant Analysis

System administrators must upgrade the bandit dependency to version 1.11.0 or later. This release enforces the max_fragmented_message_size constraint, terminating excessive memory allocations during fragment reassembly. Operators should evaluate whether their application workflows require fragmented payloads larger than the 8MB default and adjust the configuration parameter accordingly.

The official patch mitigates a secondary risk by rejecting zero-length non-final continuation frames. This validation step prevents attackers from circumventing the 8MB threshold by transmitting billions of empty frames to induce CPU exhaustion via infinite loop processing.

Variant attack vectors remain theoretically possible despite the patch. The IO.iodata_length/1 function operates with O(N) time complexity. An attacker streaming a massive volume of extremely small continuation frames forces repeated O(N) list traversals, potentially causing CPU degradation. Additionally, environments utilizing permessage-deflate compression evaluate the threshold against compressed payloads. Highly compressed payloads may expand in memory, bridging the gap between wire size and RAM allocation before triggering the 8MB limit.

Official Patches

Bandit GitHubOfficial fix commit in bandit repository

Fix Analysis (1)

Technical Appendix

CVSS Score
8.7/ 10
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
EPSS Probability
0.06%
Top 83% most exploited

Affected Systems

Bandit HTTP Server (0.5.0 up to 1.11.0)Phoenix Web Applications using vulnerable Bandit instances as the web server adapter

Affected Versions Detail

Product
Affected Versions
Fixed Version
bandit
mtrudel
>= 0.5.0, < 1.11.01.11.0
AttributeDetail
CWE IDCWE-770
Attack VectorNetwork (Unauthenticated)
CVSS 4.0 Score8.7 (High)
EPSS Percentile17.28%
Primary ImpactDenial of Service (OOM)
Exploit StatusNone (Theoretical PoC)
CISA KEVNo

MITRE ATT&CK Mapping

T1499.003Endpoint Denial of Service: OS Exhaustion
Impact
CWE-770
Allocation of Resources Without Limits or Throttling

Allocation of Resources Without Limits or Throttling

Vulnerability Timeline

Vulnerability published by Erlang Ecosystem Foundation (EEF) CNA
2026-05-01
Fix commit merged and version 1.11.0 released
2026-05-01
CVE record updated with full description and CVSS vectors
2026-05-04

References & Sources

  • [1]NVD - CVE-2026-42786
  • [2]GitHub Advisory GHSA-pf94-94m9-536p
  • [3]EEF CVE-2026-42786
  • [4]OSV EEF-CVE-2026-42786

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.