Zapros: Streaming decoders ignored the requested chunk size, allowing a single compressed response chunk to allocate unbounded memory (decompression bomb)
### Impact 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. ```python 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 ``` ### Patches 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. ### Workarounds For unpatched versions: - Read the still-compressed body with `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. - Where feasible, send `Accept-Encoding: id
GHSA-6cp7-3m3c-5x5c
Primary source · Revision 1
Imported from structured advisory data. Source references identify upstream records or fields; verify affected versions and your deployed configuration.
Security context
Source reference: osv:GHSA-6cp7-3m3c-5x5c
zapros
Source reference: /affected/0/package/name
- Affected versions
- 0.10.0
Source reference:
/affected/0/versions0.11.0Source reference:
/affected/0/versions0.11.1Source reference:
/affected/0/versions0.12.0Source reference:
/affected/0/versions0.13.0Source reference:
/affected/0/versions0.2.0Source reference:
/affected/0/versions0.2.1Source reference:
/affected/0/versions0.2.2Source reference:
/affected/0/versions0.2.3Source reference:
/affected/0/versions0.3.0Source reference:
/affected/0/versions0.4.0Source reference:
/affected/0/versions0.5.0Source reference:
/affected/0/versions0.5.1Source reference:
/affected/0/versions0.6.0Source reference:
/affected/0/versions0.7.0Source reference:
/affected/0/versions0.8.0Source reference:
/affected/0/versions0.9.0Source reference:
/affected/0/versions - Fixed versions
- 0.14.0
Source reference:
/affected/0/ranges - Prerequisites
- Not stated in this record
Structured affected-version data
Original package identities and version rules from this source.
[
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "0"
},
{
"fixed": "0.14.0"
}
]
}
],
"package": {
"name": "zapros",
"purl": "pkg:pypi/zapros",
"ecosystem": "PyPI"
},
"versions": [
"0.10.0",
"0.11.0",
"0.11.1",
"0.12.0",
"0.13.0",
"0.2.0",
"0.2.1",
"0.2.2",
"0.2.3",
"0.3.0",
"0.4.0",
"0.5.0",
"0.5.1",
"0.6.0",
"0.7.0",
"0.8.0",
"0.9.0"
],
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-6cp7-3m3c-5x5c/GHSA-6cp7-3m3c-5x5c.json"
}
}
]- Related CVEs
- CVE-2026-61652
Source reference:
/aliases
Publisher severity
high
Source reference: /database_specific/severity
- Event
- #62546 · Revision 1
- Added to Heist Feed
- Publisher date