Skip to content

urllib3 1.26.20.post4

Latest

Choose a tag to compare

@icanhasmath icanhasmath released this 23 Oct 02:13
· 987 commits to main since this release
d885081

ActiveState security release of urllib3 1.26.20 for the Python 2.7-compatible line.

Fixed

  • CVE-2025-66471 / GHSA-2xpw-w6gg-jr37 (High): the streaming API (read(amt), stream(), read_chunked()) no longer fully decompresses small amounts of highly compressed data in one operation. Decoding is bounded by the requested amount, and the rest is kept for later reads. Ported from urllib3 2.6.0.
    • Bounded Brotli decoding needs Brotli ≥ 1.2.0, which ships Python 2.7 wheels. Older Brotli and brotlipy still decode correctly, but without a bound, and emit a DependencyWarning.
  • Hardening included with the port:
    • The Deflate decoder no longer loops forever on data after the end of a stream. This is the fix for upstream CVE-2026-97688 / GHSA-gh4c-6fx4-qh6g, which the bounded decoder would otherwise have brought in.
    • drain_conn() discards the rest of a body without decoding it, 64 KiB at a time (from CVE-2026-44432 / GHSA-mf9v-mfxr-j63j).
    • stream(0) and read_chunked(0) return instead of looping.
    • The decoder is flushed when a body ends, so bounded reads never drop its last bytes. This includes raw deflate sent with Content-Length, which still truncates on upstream 2.6.0–2.8.0.

Behaviour changes

  • read(amt) on a compressed response returns at most about amt decoded bytes. Any remaining output comes back on later reads.
  • To read a compressed body in pieces, use stream(). closed can be True while read(amt) still has decoded data to return.
  • read(decode_content=False) after a successful decode, while decoded data is still pending, raises RuntimeError instead of losing that data. It's still allowed after a failed decode.

Versioning

The package version is 1.26.20.post4, while urllib3.__version__ is now "1.26.20" (it was "1.26.20.post3" in post3). requests reads __version__ as major.minor.patch and warns on anything longer. The User-Agent header is python-urllib3/1.26.20.

Tested on Python 2.7.18. Changes: #4. Dists and SLSA provenance are attached by the publish workflow.