Denial of service via memory exhaustion. Affects all callers who streamed compressed responses relying on the chunk size — explicit (iter_bytes(chunk_size=...)) or the default — to bound memory. The decoder ignored that bound, so a chunk could be far larger than requested and a single compressed response could overflow memory.
import gzip, zapros
# Server returns ~1 GiB of zeros gzip-compressed to ~1 MiB,
# with header: Content-Encoding: gzip
bomb = gzip.compress(b"\0" * 1_000_000_000) # ~1 MiB on the wire
with zapros.stream("GET", "https://malicious.example/bomb") as response:
# Caller asks for 8 KiB chunks, expecting bounded memory:
for chunk in response.iter_bytes(chunk_size=8192):
... # first `chunk` is ~1 GiB, not 8 KiB -> memory exhaustion
Upgrade to 0.14.0 or later. The decoders now bound the output of each decompression step to the requested chunk_size: gzip/deflate via zlib's max_length + unconsumed_tail, brotli via output_buffer_limit, and zstd via a bounded stream_writer. Peak memory during streaming decode is now proportional to chunk_size for all supported encodings.
For unpatched versions:
Response.iter_raw() / Response.async_iter_raw(), which bypass the built-in decoders, and decompress it yourself with an explicit output-size bound (e.g. zlib's max_length), aborting once a configured limit is exceeded.Accept-Encoding: identity to disable response compression so bodies are not decompressed client-side.{
"cwe_ids": [
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-23T13:57:48Z",
"nvd_published_at": "2026-09-21T22:16:57Z",
"severity": "HIGH"
}