Описание
httplib2: Decompression Bomb Denial of Service via Unbounded gzip/deflate Response Handling
Summary
The httplib2 HTTP client library performs unbounded decompression of HTTP response bodies encoded with Content-Encoding: gzip or deflate. A malicious or compromised HTTP server can return a small compressed payload (approximately 150 KB) that expands to an arbitrarily large size in memory (150 MB or more), causing MemoryError or OOM-kill in the client process. This is a classic decompression bomb (zip bomb) attack against the HTTP client.
Any application using httplib2.Http().request() against untrusted or attacker-controlled HTTP endpoints is affected.
Details
Affected code: httplib2/__init__.py - _decompressContent() function
The decompression path has two unbounded operations:
-
gzip decompression (line 394):
content = gzip.GzipFile(fileobj=io.BytesIO(new_content)).read()The
.read()call with no size argument decompresses the entire gzip payload into a single in-memory bytes object. There is no limit on the decompressed size. -
deflate decompression (line 397):
content = zlib.decompress(content, zlib.MAX_WBITS)Similarly,
zlib.decompress()returns the fully decompressed content as a single bytes object with no size bound. -
Automatic invocation (line 1431):
_decompressContent()is called automatically on every HTTP response that includes aContent-Encoding: gzipordeflateheader. The full compressed body is already buffered in memory viaresponse.read()before decompression begins.
Root cause: There is no max_decompressed_size, streaming decompression with size tracking, or decompression ratio check anywhere in the decompression path. The library unconditionally trusts the server's compressed payload size.
Attack vector: Any HTTP server (including man-in-the-middle attackers or compromised upstream services) can trigger this by returning a response with:
Content-Encoding: gzipheader- A small compressed body that decompresses to an arbitrarily large size
Proof of Concept
Step 1 - Start a malicious HTTP server that serves a gzip decompression bomb:
Step 2 - Run the httplib2 client (in a separate terminal):
Expected output (client):
Reproduction metrics:
- Compressed payload size: 152,908 bytes (~150 KB)
- Decompressed size: 157,286,400 bytes (150 MB)
- Amplification ratio: ~1,029x
- Client memory limit: 180 MB ->
MemoryErrortriggered duringgzip.GzipFile.read()
Impact
Severity: High
Any application using httplib2 to make HTTP requests to untrusted servers is vulnerable. The attack requires no authentication, no special configuration, and no user interaction - the server simply returns a crafted gzip-compressed response.
| Parameter | Value |
|---|---|
| Compressed payload | ~150 KB |
| Decompressed size | 150 MB (configurable by attacker) |
| Amplification ratio | ~1,029x |
| Authentication required | None |
| User interaction required | None |
| Prerequisites | Client makes any HTTP request to attacker-controlled server |
Real-world scenarios:
- Web scrapers/crawlers that fetch pages from untrusted URLs
- API clients connecting to third-party services
- Webhook handlers that follow redirects to attacker-controlled endpoints
- CI/CD pipelines that download dependencies or artifacts over HTTP
- Any MITM attacker on an unencrypted HTTP connection can inject the compressed payload
Impact scaling: The attacker can create arbitrarily large decompression bombs. A 1 MB compressed payload can decompress to several gigabytes, guaranteeing OOM-kill on virtually any system. The attack is fully deterministic and requires only a single HTTP response.
Downstream exposure: httplib2 is a widely used Python HTTP client library with millions of downloads. It is a dependency of Google's API client libraries (google-api-python-client, google-auth-httplib2), meaning applications using Google Cloud APIs may be indirectly affected if they process responses from untrusted intermediaries.
Credit
Found by a security research team from the University of Sydney, focusing on detecting open source software vulnerabilities. Liyi Zhou: https://lzhou1110.github.io/ Ziyue Wang: https://zyy0530.github.io/ Strick: https://str1ckl4nd.github.io/ Maurice: https://maurice.busystar.org/ Chenchen Yu: https://7thparkk.github.io/
Ссылки
- https://github.com/httplib2/httplib2/security/advisories/GHSA-j5g9-f88f-gfj3
- https://nvd.nist.gov/vuln/detail/CVE-2026-59939
- https://github.com/httplib2/httplib2/commit/87581ad6cf752fe3da2090c59058261d2d00a427
- https://github.com/httplib2/httplib2/releases/tag/v0.32.0
- https://github.com/pypa/advisory-database/tree/main/vulns/httplib2/PYSEC-2026-3444.yaml
Пакеты
httplib2
< 0.32.0
0.32.0
Связанные уязвимости
httplib2 is a comprehensive HTTP client library for Python. Prior to 0.32.0, httplib2 performs unbounded decompression of HTTP response bodies encoded with Content-Encoding: gzip or deflate in _decompressContent in httplib2/init.py, allowing a malicious or compromised HTTP server to return a small compressed payload that expands to an arbitrarily large size in memory and causes MemoryError or OOM-kill in the client process. This issue is fixed in version 0.32.0.
httplib2 is a comprehensive HTTP client library for Python. Prior to 0.32.0, httplib2 performs unbounded decompression of HTTP response bodies encoded with Content-Encoding: gzip or deflate in _decompressContent in httplib2/init.py, allowing a malicious or compromised HTTP server to return a small compressed payload that expands to an arbitrarily large size in memory and causes MemoryError or OOM-kill in the client process. This issue is fixed in version 0.32.0.
httplib2 is a comprehensive HTTP client library for Python. Prior to 0.32.0, httplib2 performs unbounded decompression of HTTP response bodies encoded with Content-Encoding: gzip or deflate in _decompressContent in httplib2/init.py, allowing a malicious or compromised HTTP server to return a small compressed payload that expands to an arbitrarily large size in memory and causes MemoryError or OOM-kill in the client process. This issue is fixed in version 0.32.0.
httplib2 is a comprehensive HTTP client library for Python. Prior to 0 ...