CVE-2026-42786
WebSocket fragmented message reassembly unbounded in bandit
Allocation of Resources Without Limits or Throttling vulnerability in mtrudel bandit allows unauthenticated remote denial of service via memory exhaustion.
The fragment reassembly path in 'Elixir.Bandit.WebSocket.Connection':handle_frame/3 in lib/bandit/websocket/connection.ex appends every incoming Continuation{fin: false} frame's payload to a per-connection iolist with no cumulative size cap. The existing max_frame_size option only bounds individual frames; a peer that streams an unbounded number of continuation frames without ever setting fin=1 grows BEAM heap linearly until the OS or a supervisor kills the process.
Because the accumulation happens before WebSock.handle_in/2 is called, the application has no opportunity to interpose a size check. Phoenix Channels and LiveView both run over WebSock on Bandit, so a stock Phoenix application exposes this surface as soon as it accepts socket connections.
This issue affects bandit: from 0.5.0 before 1.11.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.7
WebSocket fragmented message reassembly unbounded in bandit
Allocation of Resources Without Limits or Throttling vulnerability in mtrudel bandit allows unauthenticated remote denial of service via memory exhaustion.
The fragment reassembly path in 'Elixir.Bandit.WebSocket.Connection':handle_frame/3 in lib/bandit/websocket/connection.ex appends every incoming Continuation{fin: false} frame's payload to a per-connection iolist with no cumulative size cap. The existing max_frame_size option only bounds individual frames; a peer that streams an unbounded number of continuation frames without ever setting fin=1 grows BEAM heap linearly until the OS or a supervisor kills the process.
Because the accumulation happens before WebSock.handle_in/2 is called, the application has no opportunity to interpose a size check. Phoenix Channels and LiveView both run over WebSock on Bandit, so a stock Phoenix application exposes this surface as soon as it accepts socket connections.
This issue affects bandit: from 0.5.0 before 1.11.0.
- Record
CVE-2026-42786- CVSS 4.0
- 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 - Weakness
- CWE-770
- Updated
- 2026-11-02
EUVDEUVD-2026-26715
8.7
Allocation of Resources Without Limits or Throttling vulnerability in mtrudel bandit allows unauthenticated remote denial of service via memory exhaustion.
The fragment reassembly path in 'Elixir.Bandit.WebSocket.Connection':handle_frame/3 in lib/bandit/websocket/connection.ex appends every incoming Continuation{fin: false} frame's payload to a per-connection iolist with no cumulative size cap. The existing max_frame_size option only bounds individual frames; a peer that streams an unbounded number of continuation frames without ever setting fin=1 grows BEAM heap linearly until the OS or a supervisor kills the process.
Because the accumulation happens before WebSock.handle_in/2 is called, the application has no opportunity to interpose a size check. Phoenix Channels and LiveView both run over WebSock on Bandit, so a stock Phoenix application exposes this surface as soon as it accepts socket connections.
This issue affects bandit: from 0.5.0 before 1.11.0.
- Record
EUVD-2026-26715- CVSS 4.0
- 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 - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-pf94-94m9-536p
8.7
Bandit Buffers Unbounded WebSocket Continuation Frames, Allowing Unauthenticated Memory Exhaustion
Summary
A single unauthenticated WebSocket client can exhaust server memory in any Bandit-fronted application that accepts WebSocket connections. The fragmented-message reassembly path appends every Continuation{fin: false} frame's payload to a per-connection iolist with no cumulative size cap, so a peer that streams continuation frames indefinitely (never setting fin=1) grows BEAM heap linearly until the OS or a supervisor kills the process. max_frame_size only bounds individual frames; there is no max_message_size option available today.
Details
The bug is in lib/bandit/websocket/connection.ex, in the fragment branch of handle_frame/3 (around lines 80–95). When a non-final continuation arrives, Bandit builds the next accumulator as [connection.fragment_frame.data | frame.data] with no running byte-count check. A peer can therefore stream max-sized continuations forever and grow BEAM resident memory without bound. When fin=1 finally arrives (if ever), IO.iodata_to_binary/1 flattens the whole iolist, briefly doubling peak memory. The attacker does not need to send fin=1 — simply holding the connection open is enough to pin the bytes.
Suggested fix: track a running cumulative byte count on the connection state and add a configurable max_message_size. When exceeded, terminate the connection with RFC 6455 close code 1009 (:max_message_size_exceeded) instead of continuing to append.
PoC
A self-contained reproduction script is below. It starts Bandit 1.10 on 127.0.0.1:4321 with a trivial WebSock echo handler, completes a WebSocket handshake, sends one text frame with fin=0, then streams up to 4096 continuation frames of 1 MiB each — also fin=0. A background sampler logs :erlang.memory(:total) every 250 ms.
A correctly-fixed server would close the connection with code 1009 once max_message_size is exceeded.
Impact
Unauthenticated DoS via memory exhaustion. A single connection can drive BEAM heap to gigabytes; a small number of concurrent connections OOM-kills the host.
Affected by default. No opt-in flag, no configuration option to mitigate. Any Phoenix application is on the vulnerable path: Phoenix Channels and LiveView both run over WebSock on Bandit, so a stock Phoenix app exposes this surface as soon as it accepts socket connections — including the LiveView socket that almost every Phoenix 1.7+ app mounts at /live. Plug apps that mount any custom WebSock handler are equally affected. Applications that expose no WebSocket endpoints are not.
The exploit also survives almost every common deployment topology: L4 load balancers, HTTP-mode reverse proxies, and TLS-terminating edge proxies (Cloudflare, Fly.io, Fastly, etc.) all tunnel post-upgrade WebSocket frames opaquely without inspecting size. There is no application-level workaround either — the accumulation happens before WebSock.handle_in/2 is called, so by the time the application could check, Bandit has already buffered the iolist. The fix belongs in Bandit.
Script and Logs
# Bandit WebSocket fragmented-message accumulation PoC.
#
# lib/bandit/websocket/connection.ex:80-95 appends every incoming
# Continuation{fin: false} frame's payload to connection.fragment_frame.data
# as iodata, with no cumulative cap. `max_frame_size` only bounds *each*
# frame; a peer that streams an unbounded number of max-sized continuations
# without ever setting fin=1 grows the iolist linearly in BEAM memory until
# the OS kills the process. The eventual IO.iodata_to_binary/1 in the
# fin=true branch also momentarily doubles peak memory.
#
# This script starts Bandit 1.10 on 127.0.0.1:4321, opens a WebSocket,
# sends one text frame with fin=0 followed by a continuous stream of
# continuation frames (also fin=0), and samples BEAM memory while doing so.
# A correct server would close the connection with 1009 once a configured
# max-message-size is exceeded; the buggy server keeps growing.
#
# Run:…
- Record
GHSA-pf94-94m9-536p- CVSS 4.0
- 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 - Weakness
- CWE-770
- Updated
- 2026-11-02
NVD
8.7
Allocation of Resources Without Limits or Throttling vulnerability in mtrudel bandit allows unauthenticated remote denial of service via memory exhaustion.
The fragment reassembly path in 'Elixir.Bandit.WebSocket.Connection':handle_frame/3 in lib/bandit/websocket/connection.ex appends every incoming Continuation{fin: false} frame's payload to a per-connection iolist with no cumulative size cap. The existing max_frame_size option only bounds individual frames; a peer that streams an unbounded number of continuation frames without ever setting fin=1 grows BEAM heap linearly until the OS or a supervisor kills the process.
Because the accumulation happens before WebSock.handle_in/2 is called, the application has no opportunity to interpose a size check. Phoenix Channels and LiveView both run over WebSock on Bandit, so a stock Phoenix application exposes this surface as soon as it accepts socket connections.
This issue affects bandit: from 0.5.0 before 1.11.0.
- Record
CVE-2026-42786- CVSS 4.0
- 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 - Weakness
- CWE-770
- Updated
- 2026-11-02
OSV
8.7
WebSocket fragmented message reassembly unbounded in bandit
Allocation of Resources Without Limits or Throttling vulnerability in mtrudel bandit allows unauthenticated remote denial of service via memory exhaustion.
The fragment reassembly path in 'Elixir.Bandit.WebSocket.Connection':handle_frame/3 in lib/bandit/websocket/connection.ex appends every incoming Continuation{fin: false} frame's payload to a per-connection iolist with no cumulative size cap. The existing max_frame_size option only bounds individual frames; a peer that streams an unbounded number of continuation frames without ever setting fin=1 grows BEAM heap linearly until the OS or a supervisor kills the process.
Because the accumulation happens before WebSock.handle_in/2 is called, the application has no opportunity to interpose a size check. Phoenix Channels and LiveView both run over WebSock on Bandit, so a stock Phoenix application exposes this surface as soon as it accepts socket connections.
This issue affects bandit: from 0.5.0 before 1.11.0.
- Record
CVE-2026-42786- CVSS 4.0
- 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 - Weakness
- CWE-770
- Updated
- 2026-11-02
OSVEEF-CVE-2026-42786
8.7
WebSocket fragmented message reassembly unbounded in bandit
Summary
Allocation of Resources Without Limits or Throttling vulnerability in mtrudel bandit allows unauthenticated remote denial of service via memory exhaustion.
The fragment reassembly path in 'Elixir.Bandit.WebSocket.Connection':handle_frame/3 in lib/bandit/websocket/connection.ex appends every incoming Continuation{fin: false} frame's payload to a per-connection iolist with no cumulative size cap. The existing max_frame_size option only bounds individual frames; a peer that streams an unbounded number of continuation frames without ever setting fin=1 grows BEAM heap linearly until the OS or a supervisor kills the process.
Because the accumulation happens before WebSock.handle_in/2 is called, the application has no opportunity to interpose a size check. Phoenix Channels and LiveView both run over WebSock on Bandit, so a stock Phoenix application exposes this surface as soon as it accepts socket connections.
This issue affects bandit: from 0.5.0 before 1.11.0.
Configurations
The application must accept WebSocket connections. Applications that expose no WebSocket endpoints are not affected.
- Record
EEF-CVE-2026-42786- CVSS 4.0
- 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 - Weakness
- CWE-770
- Updated
- 2026-11-02
OSVGHSA-pf94-94m9-536p
8.7
Bandit Buffers Unbounded WebSocket Continuation Frames, Allowing Unauthenticated Memory Exhaustion
Summary
A single unauthenticated WebSocket client can exhaust server memory in any Bandit-fronted application that accepts WebSocket connections. The fragmented-message reassembly path appends every Continuation{fin: false} frame's payload to a per-connection iolist with no cumulative size cap, so a peer that streams continuation frames indefinitely (never setting fin=1) grows BEAM heap linearly until the OS or a supervisor kills the process. max_frame_size only bounds individual frames; there is no max_message_size option available today.
Details
The bug is in lib/bandit/websocket/connection.ex, in the fragment branch of handle_frame/3 (around lines 80–95). When a non-final continuation arrives, Bandit builds the next accumulator as [connection.fragment_frame.data | frame.data] with no running byte-count check. A peer can therefore stream max-sized continuations forever and grow BEAM resident memory without bound. When fin=1 finally arrives (if ever), IO.iodata_to_binary/1 flattens the whole iolist, briefly doubling peak memory. The attacker does not need to send fin=1 — simply holding the connection open is enough to pin the bytes.
Suggested fix: track a running cumulative byte count on the connection state and add a configurable max_message_size. When exceeded, terminate the connection with RFC 6455 close code 1009 (:max_message_size_exceeded) instead of continuing to append.
PoC
A self-contained reproduction script is below. It starts Bandit 1.10 on 127.0.0.1:4321 with a trivial WebSock echo handler, completes a WebSocket handshake, sends one text frame with fin=0, then streams up to 4096 continuation frames of 1 MiB each — also fin=0. A background sampler logs :erlang.memory(:total) every 250 ms.
A correctly-fixed server would close the connection with code 1009 once max_message_size is exceeded.
Impact
Unauthenticated DoS via memory exhaustion. A single connection can drive BEAM heap to gigabytes; a small number of concurrent connections OOM-kills the host.
Affected by default. No opt-in flag, no configuration option to mitigate. Any Phoenix application is on the vulnerable path: Phoenix Channels and LiveView both run over WebSock on Bandit, so a stock Phoenix app exposes this surface as soon as it accepts socket connections — including the LiveView socket that almost every Phoenix 1.7+ app mounts at /live. Plug apps that mount any custom WebSock handler are equally affected. Applications that expose no WebSocket endpoints are not.
The exploit also survives almost every common deployment topology: L4 load balancers, HTTP-mode reverse proxies, and TLS-terminating edge proxies (Cloudflare, Fly.io, Fastly, etc.) all tunnel post-upgrade WebSocket frames opaquely without inspecting size. There is no application-level workaround either — the accumulation happens before WebSock.handle_in/2 is called, so by the time the application could check, Bandit has already buffered the iolist. The fix belongs in Bandit.
Script and Logs
# Bandit WebSocket fragmented-message accumulation PoC.
#
# lib/bandit/websocket/connection.ex:80-95 appends every incoming
# Continuation{fin: false} frame's payload to connection.fragment_frame.data
# as iodata, with no cumulative cap. `max_frame_size` only bounds *each*
# frame; a peer that streams an unbounded number of max-sized continuations
# without ever setting fin=1 grows the iolist linearly in BEAM memory until
# the OS kills the process. The eventual IO.iodata_to_binary/1 in the
# fin=true branch also momentarily doubles peak memory.
#
# This script starts Bandit 1.10 on 127.0.0.1:4321, opens a WebSocket,
# sends one text frame with fin=0 followed by a continuous stream of
# continuation frames (also fin=0), and samples BEAM memory while doing so.
# A correct server would close the connection with 1009 once a configured
# max-message-size is exceeded; the buggy server keeps growing.
#
# Run:…
- Record
GHSA-pf94-94m9-536p- CVSS 4.0
- 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 - Weakness
- CWE-770
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
banditHex |
0.5.0 up to 1.11.0 | 1.11.0 |
banditHex |
0.5.0 up to 1.11.0, plus listed versions 0.5.10.5.100.5.110.5.20.5.3 Show 45 moreShow less0.5.40.5.50.5.60.5.70.5.80.5.90.6.00.6.10.6.100.6.110.6.20.6.30.6.40.6.50.6.60.6.70.6.80.6.90.7.00.7.10.7.20.7.30.7.40.7.50.7.60.7.71.0.01.0.0-pre.11.0.0-pre.101.0.0-pre.111.0.0-pre.121.0.0-pre.131.0.0-pre.141.0.0-pre.151.0.0-pre.161.0.0-pre.171.0.0-pre.181.0.0-pre.21.0.0-pre.31.0.0-pre.41.0.0-pre.51.0.0-pre.61.0.0-pre.71.0.0-pre.81.0.0-pre.9 |
1.11.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-42786 is a high vulnerability (CVSS 8.7) in Mtrudel Bandit, published May 1, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.65%, the 51st percentile. Fixed in bandit 1.11.0.
References
Left out here: 40 versions and the rest of 2 source descriptions. The JSON record has them.