May 5, 2026·6 min read·11 visits
An unauthenticated remote attacker can crash the Prometheus server by sending a minimal, crafted Snappy payload to the remote read endpoint, triggering excessive memory allocation and an immediate Out-of-Memory (OOM) condition.
Prometheus versions prior to 3.5.3 and 3.6.0 through 3.11.2 are vulnerable to a Denial of Service (DoS) attack. The `/api/v1/read` endpoint improperly handles compressed request bodies, allowing an unauthenticated attacker to exhaust server memory using a crafted Snappy payload. This memory exhaustion causes the underlying process to terminate, rendering the monitoring infrastructure completely unavailable.
Prometheus exposes the /api/v1/read endpoint to facilitate remote read operations, allowing external clients to query time-series data. This endpoint accepts HTTP POST requests containing payload data compressed with the Snappy algorithm. The system relies on the snappy-go library to decompress incoming streams before parsing the underlying query protocol.
The vulnerability, tracked as CVE-2026-42154, constitutes an uncontrolled resource consumption flaw (CWE-400) and memory allocation with excessive size value (CWE-789). It arises because the endpoint does not validate the uncompressed size declared in the Snappy stream header before initiating the decompression process.
By transmitting a specifically constructed payload, an unauthenticated attacker can force the Prometheus server to allocate large amounts of heap memory. This behavior directly leads to memory exhaustion. The operating system OOM killer subsequently terminates the Prometheus process, resulting in a complete denial of service.
The root cause resides in the DecodeReadRequest function within storage/remote/codec.go. When processing incoming requests, the application directly invokes snappy.Decode(nil, compressed) on the HTTP request body.
The Snappy compression format encodes the expected decompressed data size as a varint (variable-length integer) at the very beginning of the stream. The Go implementation of the Snappy decoder reads this varint and immediately allocates a destination byte slice of that exact capacity to hold the uncompressed data.
The flaw occurs because the application performs no bounds checking on this decoded length value prior to the allocation step. A stream header can declare a multi-gigabyte decompressed size while the actual compressed payload is only a few bytes long. The Go runtime obediently attempts to provision the requested memory, leading to an immediate spike in memory consumption.
The vulnerable implementation simply passes the raw byte slice to the decoding function. The absence of a safety check means the snappy-go library dictates the allocation behavior based entirely on untrusted user input.
The following code illustrates the relevant modifications introduced in the patch. The developers implemented a validation step utilizing snappy.DecodedLen to read the varint header without allocating the memory required for the full decompression.
// Vulnerable Implementation
// reqBuf, err := snappy.Decode(nil, compressed)
// Patched Implementation
decodedLen, err := snappy.DecodedLen(compressed)
if err != nil {
return nil, err
}
// decodeReadLimit is established at 32 MiB (33,554,432 bytes)
if decodedLen > decodeReadLimit {
return nil, fmt.Errorf("snappy: decoded length %d exceeds limit %d", decodedLen, decodeReadLimit)
}
reqBuf, err := snappy.Decode(nil, compressed)This fix is complete for this specific endpoint. By enforcing a hard limit of 32 MiB on the expected decompressed size, the application prevents arbitrary heap allocations. Requests exceeding this threshold are rejected synchronously before any substantial memory is requested from the runtime.
Exploitation requires network access to the Prometheus /api/v1/read endpoint. No authentication is necessary, lowering the barrier to entry for prospective attackers. The attack vector relies on generating a "Snappy Bomb," a highly compressed data structure designed to trigger the allocation flaw.
An attacker constructs a minimal byte sequence representing a valid Snappy stream header. For instance, a 5-byte sequence 0x80 0x80 0x80 0x80 0x01 decodes to a varint representing 268,435,456 bytes (256 MiB). The attacker packages this header into an HTTP POST request and transmits it to the target endpoint.
// Proof of Concept logic simulating the attack
bomb := []byte{0x80, 0x80, 0x80, 0x80, 0x01}
req, err := http.NewRequest(http.MethodPost, "/api/v1/read", bytes.NewReader(bomb))A single request consumes 256 MiB of memory. By issuing multiple concurrent requests, the attacker compounds the memory allocations rapidly. A simple script can easily exhaust the physical memory of a standard server within seconds, triggering a swift denial of service.
The following diagram illustrates the sequence of events during a successful exploitation attempt. It details the flow from the initial malicious request to the eventual process termination by the operating system.
The process highlights the critical failure point at the boundary between the application logic and the compression library. The application trusts the compression library to handle the stream safely, while the library trusts the stream header to represent legitimate data requirements.
The primary impact of CVE-2026-42154 is a severe reduction in availability. Prometheus operates as a critical infrastructure component used for monitoring and alerting. Disabling the monitoring system blinds operations teams to other potential ongoing issues or concurrent attacks within the monitored environment.
The vulnerability carries a CVSS v3.1 base score of 7.5. The attack complexity is low, and no user interaction is required. The exploit is reliable and leaves minimal traces in standard access logs beyond an influx of POST requests to the remote read endpoint.
Confidentiality and integrity remain unaffected. The attacker cannot extract metric data, modify stored time-series information, or execute arbitrary code. The damage is restricted entirely to resource exhaustion and forced process termination.
The most effective remediation strategy is to upgrade Prometheus to a patched release. Administrators must deploy version 3.5.3 or 3.11.3, which contain the upstream fixes limiting the decompressed buffer allocation to 32 MiB.
If immediate patching is not feasible, network-level mitigations reduce the attack surface. Administrators should restrict access to the /api/v1/read endpoint using firewalls, reverse proxies, or API gateways. Only trusted components and authorized IP addresses should be permitted to interact with the remote read functionality.
Implementing a Web Application Firewall (WAF) rule to block POST requests to /api/v1/read entirely serves as a temporary workaround if the remote read feature is not actively utilized. Additionally, configuring strict memory limits via container orchestration platforms ensures that a Prometheus crash does not affect co-located services on the same node.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Prometheus Prometheus Project | < 3.5.3 | 3.5.3 |
Prometheus Prometheus Project | >= 3.6.0, < 3.11.3 | 3.11.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400, CWE-789 |
| Attack Vector | Network |
| CVSS v3.1 Score | 7.5 (High) |
| Impact | Denial of Service (Memory Exhaustion / OOM) |
| Exploit Status | Proof of Concept (PoC) available |
| Authentication | None required |
Uncontrolled Resource Consumption and Memory Allocation with Excessive Size Value