VYPR
High severityNVD Advisory· Published Dec 5, 2025· Updated Dec 5, 2025

urllib3 allows an unbounded number of links in the decompression chain

CVE-2025-66418

Description

urllib3 is a user-friendly HTTP client library for Python. Starting in version 1.24 and prior to 2.6.0, the number of links in the decompression chain was unbounded allowing a malicious server to insert a virtually unlimited number of compression steps leading to high CPU usage and massive memory allocation for the decompressed data. This vulnerability is fixed in 2.6.0.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
urllib3PyPI
>= 1.24, < 2.6.02.6.0

Affected products

1

Patches

1
24d7b67eac89

Merge commit from fork

https://github.com/urllib3/urllib3Illia VolochiiDec 5, 2025via ghsa
3 files changed · +25 1
  • changelog/GHSA-gm62-xv2j-4w53.security.rst+4 0 added
    @@ -0,0 +1,4 @@
    +Fixed a security issue where an attacker could compose an HTTP response with
    +virtually unlimited links in the ``Content-Encoding`` header, potentially
    +leading to a denial of service (DoS) attack by exhausting system resources
    +during decoding. The number of allowed chained encodings is now limited to 5.
    
  • src/urllib3/response.py+11 1 modified
    @@ -306,8 +306,18 @@ class MultiDecoder(ContentDecoder):
             they were applied.
         """
     
    +    # Maximum allowed number of chained HTTP encodings in the
    +    # Content-Encoding header.
    +    max_decode_links = 5
    +
         def __init__(self, modes: str) -> None:
    -        self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")]
    +        encodings = [m.strip() for m in modes.split(",")]
    +        if len(encodings) > self.max_decode_links:
    +            raise DecodeError(
    +                "Too many content encodings in the chain: "
    +                f"{len(encodings)} > {self.max_decode_links}"
    +            )
    +        self._decoders = [_get_decoder(e) for e in encodings]
     
         def flush(self) -> bytes:
             return self._decoders[0].flush()
    
  • test/test_response.py+10 0 modified
    @@ -847,6 +847,16 @@ def test_read_multi_decoding_deflate_deflate(self) -> None:
             assert r.read(9 * 37) == b"foobarbaz" * 37
             assert r.read() == b""
     
    +    def test_read_multi_decoding_too_many_links(self) -> None:
    +        fp = BytesIO(b"foo")
    +        with pytest.raises(
    +            DecodeError, match="Too many content encodings in the chain: 6 > 5"
    +        ):
    +            HTTPResponse(
    +                fp,
    +                headers={"content-encoding": "gzip, deflate, br, zstd, gzip, deflate"},
    +            )
    +
         def test_body_blob(self) -> None:
             resp = HTTPResponse(b"foo")
             assert resp.data == b"foo"
    

Vulnerability mechanics

Synthesis attempt was rejected by the grounding validator. Re-run pending.

References

4

News mentions

0

No linked articles in our index yet.