CVE-2026-49755
Summary
Req's default response pipeline auto-decodes archive and compressed bodies based on the server-supplied content-type (or URL extension) and materialises the full decompressed contents in memory with no size cap. An attacker who controls (or can redirect a victim into) an HTTP endpoint reached by Req.get!/1 can return a tiny "decompression bomb" that expands to many gigabytes on the client and exhausts the BEAM's memory.
Details
1. Archive auto-decoding. Req.Steps.decode_body/1 in lib/req/steps.ex dispatches on the response content-type (or URL extension) and calls Erlang's archive libraries with :memory, returning a [{name, bytes}] list of every entry fully decompressed in RAM: application/zip → :zip.extract(body, [:memory]), application/x-tar → :erl_tar.extract({:binary, body}, [:memory]), application/gzip / .tgz → :erl_tar.extract({:binary, body}, [:memory, :compressed]). No byte cap is enforced before decoding and no per-entry size limit is passed to :zip / :erl_tar.
2. content-encoding chaining. Req.Steps.decompress_body/1 walks the content-encoding header and chains :zlib / :brotli / :ezstd decoders, so a response advertising content-encoding: gzip, gzip, gzip, … inflates through multiple layers without bound.
3. Default-on, attacker-chosen decoder. Both steps are part of Req's default pipeline. The caller does not need to opt in, and the attacker chooses which decoder fires by setting content-type and content-encoding on their own server (or on any host reached via Req's automatic redirect following).
PoC
1. Run an HTTP server that responds 200 with content-type: application/zip and a body that is a zip archive whose single entry is ~400 MB of zero bytes (compressed wire payload: a few hundred KB).
2. From the victim process, call Req.get!(url) against that server (no special options, no opt-in to archive decoding).
3. decode_body/1 dispatches on content-type, invokes :zip.extract(body, [:memory]), and the response body becomes [{~c"bomb.bin", <
⚡ Watch CVE-2026-49755
Get an email if CVE-2026-49755 is added to CISA KEV, gains public exploit code, or a new advisory cites it — max one per day, one-click unsubscribe.
Exploitation outlook
- Low exploitation risk0.44% 30-day exploitation probability — currently an unlikely target, but scores change as exploit code circulates. Riskier than 36% of all EPSS-scored CVEs.
Advisory coverage (1)
External references
Embed the live status
— this badge updates automatically when the KEV or exploit status changes. How to embed it →
[](https://www.csirts.com/cve/CVE-2026-49755)