Bandit, WebSocket Memory Exhaustion via Fragmented Continuation Frames, critical

Listen to this Post

The vulnerability (no formal CVE assigned yet) exists in Bandit’s WebSocket fragmented‑message reassembly logic. In `lib/bandit/websocket/connection.ex` (lines 80–95), when a WebSocket frame with `fin=0` (non‑final fragment) arrives, Bandit stores its payload in a per‑connection iolist accumulator as [connection.fragment_frame.data | frame.data]. There is no cumulative byte‑count check for the entire reassembled message. The existing `max_frame_size` option only limits each individual frame’s payload, not the sum of all fragments.
An unauthenticated attacker completing a WebSocket handshake sends a single text frame with `fin=0` (opcode 0x1) followed by an endless stream of continuation frames (opcode 0x0) also with fin=0. Each continuation frame can be as large as `max_frame_size` (default ~16 MiB). Bandit blindly appends each payload to the iolist, causing the BEAM heap to grow linearly with every new frame. The attacker never sends a final `fin=1` frame, so the iolist is never flattened by `IO.iodata_to_binary/1` – but simply holding the connection open pins all bytes in memory. Memory consumption rises until the operating system OOM‑kills the Beam process or a supervisor terminates it. Even if a `fin=1` eventually arrives, flattening the iolist temporarily doubles peak memory usage. No `max_message_size` configuration exists to cap the total accumulated size.
Because the accumulation happens before `WebSock.handle_in/2` is called, application‑level checks cannot mitigate it. The issue affects all Phoenix 1.7+ apps (LiveView socket at /live) and any Plug app that mounts a `WebSock` handler. Deployed topologies (L4 load balancers, TLS‑terminating proxies, Cloudflare, etc.) tunnel WebSocket frames opaquely and do not block the attack. A single connection can drive memory to gigabytes; a few concurrent connections exhaust the host.

dailycve form:

Platform: Bandit / Elixir
Version: 1.10 and earlier
Vulnerability : Unbounded WebSocket fragments
Severity: Critical (DoS)
date: 2026-05-07

Prediction: Patch in 7‑14 days

Analytics under heading What Undercode Say:

Monitor BEAM memory while exploit runs
while true; do echo "$(date) $(ps aux | grep beam | grep -v grep | awk '{print $6}')"; sleep 2; done
Quick test for vulnerable Bandit (requires Elixir)
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" http://127.0.0.1:4321/

Elixir PoC fragment (core loop):

payload = :binary.copy(<<0x41>>, 1_048_576)
frame = build_frame(0x0, false, payload) fin=0 continuation
Enum.each(1..4096, fn _ -> :gen_tcp.send(sock, frame) end)

Exploit:

Run the provided self‑contained Elixir script (ws_fragment_memory_exhaustion.exs) against any Bandit 1.10 server that accepts WebSocket connections. It completes a handshake, sends one `fin=0` text frame (1 MiB), then streams 4096 continuation frames (each 1 MiB, fin=0). Background memory sampling shows BEAM total growing from ~50 MiB to over 4 GiB, with no connection close. The server remains unresponsive or crashes.

Protection from this CVE:

  • Upgrade Bandit to a patched version (once released) that implements a configurable `max_message_size` and enforces RFC 6455 close code 1009.
  • Until a patch is available, block or rate‑limit WebSocket endpoints at the network edge if possible (e.g., using `mod_security` or a WAF that inspects fragment counts – rare).
  • Disable WebSocket endpoints entirely when not required: comment out `socket “/live”, Phoenix.LiveView.Socket` in Phoenix endpoint.ex.
  • Monitor BEAM memory and kill connections that accumulate abnormally large iolists via custom `:erlang.process_info` checks (complex, not a true fix).

Impact:

  • Unauthenticated Denial of Service – any remote client can exhaust server memory without credentials.
  • Default vulnerable – no opt‑in flag; all Bandit‑fronted WebSocket applications are affected.
  • Low‑complexity attack – single TCP connection, standard WebSocket framing, no amplification needed.
  • Bypasses common defenses – L4/L7 proxies, TLS terminators, and CDNs do not block fragmented WebSocket messages.
  • Production and development – identical impact; a few concurrent attackers OOM‑kill the entire BEAM node.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top