May 7, 2026·5 min read·20 visits
Unauthenticated remote attackers can trigger a Denial of Service (OOM crash) in the Bandit web server by sending a highly compressed WebSocket frame, exhausting BEAM memory if `permessage-deflate` is enabled.
CVE-2026-39804 is a critical resource exhaustion vulnerability (CWE-770) affecting the Bandit Elixir HTTP server. By exploiting unbounded DEFLATE decompression in WebSocket frames, an unauthenticated attacker can crash the Erlang VM (BEAM) via a highly compressed decompression bomb.
Bandit is an HTTP server written in Elixir, designed to support modern web protocols including WebSockets. The server implements the permessage-deflate extension, which allows clients and servers to compress WebSocket frames to reduce bandwidth usage.
CVE-2026-39804 is a resource exhaustion vulnerability within this decompression implementation. The vulnerability triggers an Out-of-Memory (OOM) condition in the underlying Erlang Virtual Machine (BEAM) node when processing malicious inputs.
The flaw originates from unbounded memory allocation during the inflation of highly compressed data streams. Because the server does not enforce a maximum expansion ratio, a small input payload can consume gigabytes of heap memory before application-level size limits are checked.
The vulnerability exists within the inflate/2 function located in lib/bandit/websocket/permessage_deflate.ex. The root cause is the reliance on the unbounded :zlib.inflate/2 Erlang function for decompressing data streams.
When a client sends a compressed WebSocket frame, the Bandit server passes the payload directly to :zlib.inflate/2. This function processes the entire compressed input continuously, holding the uncompressed result in memory without enforcing any limits on the output size.
The DEFLATE algorithm can achieve extreme compression ratios, up to 1024:1 for highly repetitive data. An attacker can craft a 6 MiB payload consisting entirely of null bytes or repeating sequences that expands exponentially.
Bandit enforced a websocket_options.max_frame_size limit, but this setting only applied to the compressed, on-the-wire frame size. The application-level checks evaluate the frame size prior to decompression, allowing the highly compressed payload to bypass existing safeguards and expand to over 6 GiB in memory.
In versions prior to 1.11.0, the inflate/2 function utilized :zlib.inflate/2 followed by a direct conversion to binary via IO.iodata_to_binary/1. This logic materializes the entire uncompressed stream as a single contiguous binary on the BEAM heap.
# Vulnerable implementation
def inflate(data, %__MODULE__{} = context) do
inflated_data =
context.inflate_context
|> :zlib.inflate(<<data::binary, 0x00, 0x00, 0xFF, 0xFF>>)
|> IO.iodata_to_binary()
# Further processing
endThe patch implemented in commit 8156921a51e684a951221da7bc30a70a022f722e replaces this unbounded function with :zlib.safeInflate/2 and introduces a chunked processing loop. The implementation enforces a max_inflate_ratio parameter, defaulting to a 25:1 limit.
# Patched implementation
defp safe_inflate(inflate_context, {:continue, deflated}, buffer, bytes_remaining)
when bytes_remaining > 0 do
safe_inflate(
inflate_context,
:zlib.safeInflate(inflate_context, <<>>),
[buffer | deflated],
bytes_remaining - IO.iodata_length(deflated)
)
end
defp safe_inflate(_inflate_context, {:continue, _deflated}, _buffer, bytes_remaining)
when bytes_remaining <= 0 do
{:error, :too_much_inflation}
endThis recursive function evaluates the decompressed chunk size against bytes_remaining. If the cumulative uncompressed length exceeds byte_size(compressed_data) * max_inflate_ratio, the function returns an error tuple. The server subsequently terminates the connection with WebSocket status code 1009 (Message Too Big).
Exploitation requires an established WebSocket connection with the permessage-deflate extension negotiated during the initial HTTP upgrade handshake. The target server must be configured with compress: true for the WebSocket handler.
The attacker begins by constructing a decompression bomb. They generate a multi-megabyte stream of highly repetitive characters and compress it using standard DEFLATE algorithms. The resulting payload size is intentionally kept below the server's maximum frame size limit to ensure it is accepted by the initial packet handler.
The attacker transmits this compressed frame over the active WebSocket channel. The Bandit server receives the frame and attempts to inflate it entirely in memory. The process immediately requests massive memory allocation from the BEAM.
The official test suite provides an operational proof-of-concept. It uses :zlib.deflate to compress 1,000,000 ten-byte strings of repeating characters. When transmitted to a vulnerable server, this payload expands drastically and triggers the memory exhaustion condition.
The successful exploitation of CVE-2026-39804 results in a severe Denial of Service (DoS). The vulnerability forces the Erlang VM to perform a massive contiguous memory allocation, which generally exceeds system memory or container limits.
When the memory limit is breached, the operating system's OOM killer terminates the entire BEAM node. This crash halts all active connections, background jobs, and application state hosted within that Erlang instance.
The vulnerability carries a CVSS v4.0 base score of 8.2 (High). The impact is strictly confined to availability (VA:H), with no compromise of confidentiality or integrity. The attack requires no authentication and utilizes a low-complexity network vector (AV:N/AC:L).
Despite the high severity, the Exploit Prediction Scoring System (EPSS) assigns this vulnerability a low probability of exploitation (0.04%). This score reflects the conditional requirement that developers must explicitly opt into the vulnerable configuration by setting compress: true.
System administrators and developers must upgrade the bandit dependency to version 1.11.0 or later. This release introduces the max_inflate_ratio configuration and implements the chunked decompression logic to prevent memory exhaustion.
If immediate upgrading is not feasible, organizations can apply a configuration workaround. Disabling WebSocket compression fully mitigates the vulnerability. Administrators must set compress: false within the server configuration and omit the compress: true parameter when calling WebSockAdapter.upgrade/4.
Applications built on standard Phoenix and LiveView configurations remain unaffected by default. The default compress: false setting in these frameworks prevents the negotiation of the permessage-deflate extension.
Post-upgrade, security teams should monitor application logs for the {:error, :too_much_inflation} event. This log entry serves as a reliable indicator of active exploitation attempts or misconfigured clients sending anomalous data.
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| Product | Affected Versions | Fixed Version |
|---|---|---|
bandit mtrudel | >= 0.5.9, < 1.11.0 | 1.11.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 |
| Attack Vector | Network (Remote) |
| CVSS v4.0 Score | 8.2 (High) |
| EPSS Score | 0.0004 (11.83%) |
| Exploit Status | Proof-of-Concept Available |
| Impact | Denial of Service (Node Crash) |
Allocation of Resources Without Limits or Throttling
CVE-2024-29203 identifies a cross-site scripting (XSS) vulnerability in the content ingestion and parsing mechanics of TinyMCE rich text editor. Due to a failure to enforce sandbox attributes on dynamic iframe elements and safely handle legacy embed objects, unauthenticated attackers can inject malicious elements that execute scripts within the context of the parent application session.
A technical breakdown of the OS command injection vulnerability in the shell-quote NPM package (CVE-2026-9277 / GHSA-w7jw-789q-3m8p). The bug resides in the character-by-character backslash-escaping logic applied to the .op field of object-tokens within the quote() function, which fails to match and escape line terminators due to a regex matching oversight in JavaScript. This allows unauthenticated remote attackers to execute arbitrary shell commands if they can control inputs processed by this library.
A high-severity memory corruption vulnerability exists in the V8 JavaScript engine of Google Chrome before versions 149.0.7827.102/103. The flaw arises from an incorrect bounds-check elimination during JIT compilation by the TurboFan optimizer, allowing remote attackers to achieve out-of-bounds read and write access inside the sandboxed renderer process.
An improper authentication vulnerability (CWE-287) exists in the legacy, deprecated Internet Key Exchange version 1 (IKEv1) key exchange protocol implementation in Check Point Security Gateways. The vulnerability is caused by a logic flow weakness during the certificate validation process for Remote Access VPN and Mobile Access (SSL VPN) connections. An unauthenticated remote attacker can exploit this weakness to bypass user authentication entirely, establishing a fully functional Remote Access VPN connection without a valid password.
GeoNode versions prior to 4.4.5 and 5.0.2 are vulnerable to Server-Side Request Forgery (SSRF) in the service registration endpoint. Authenticated attackers with low privileges can exploit insufficient input validation in the Web Map Service (WMS) registration module to force the application server to make outbound network queries to loopback addresses, private RFC1918 subnets, link-local scopes, and cloud metadata endpoints. This technical report details the mechanics of the vulnerability, the underlying architectural flaw, and how to effectively remediate and mitigate the associated security risks.
CVE-2022-0492 is a high-severity missing authorization vulnerability in the Linux kernel's Control Groups (cgroups) v1 implementation. The flaw resides within the cgroup_release_agent_write function in kernel/cgroup/cgroup-v1.c, where the kernel fails to validate if the process writing to the release_agent file possesses administrative capabilities in the initial user namespace. This allows a local attacker inside a container with root privileges (UID 0) to abuse user namespaces, mount a cgroups v1 directory, modify the release_agent parameter, and execute arbitrary commands on the host system as host root, effectively achieving a complete container escape.