Details
### 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.
```python
from typing import cast
from zapros import (
AsyncBaseHandler,
AsyncBaseMiddleware,
BaseHandler,
BaseMiddleware,
Client,
DecodingError,
Request,
Response,
)
MAX_DECODE_LAYERS = 5
class ContentEncodingCheckMiddleware(BaseMiddleware, AsyncBaseMiddleware):
def __init__(
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:
...
```
EPSS — exploit probability
Low0.25%
estimated chance of real-world exploitation in the next 30 days — higher than 17.1% of every CVE FIRST.org scores
Refreshed 9/23/2026 — via FIRST.org's EPSS model, not CVSS — this measures likelihood of exploitation, not how severe it would be.