
A critical denial-of-service vulnerability has been disclosed in the ubiquitous Python HTTP client library urllib3 that allows a remote server to trigger excessive CPU and memory consumption by specifying an unbounded chain of content encodings in an HTTP response; the flaw affects urllib3 versions from 1.24 up to but not including 2.6.0 and is addressed in urllib3 2.6.0 with a hard limit on the decompression chain.
Background
urllib3 is one of the most widely used HTTP client libraries in the Python ecosystem, relied on directly by many projects and indirectly through high-level libraries such as Requests, botocore, and countless application packages. The library supports chained HTTP content encodings — for exampleContent-Encoding: gzip, zstd — in accordance with modern HTTP semantics, allowing servers to apply multiple compression algorithms in sequence. A flaw in the decoding pipeline meant that urllib3 would follow the entire advertised chain without enforcing a practical upper bound on the number of decompression steps.The practical result is a resource-exhaustion attack vector: a malicious or compromised server can reply with a
Content-Encoding header containing a very large number of encodings. When urllib3 attempts to decode the response, the client will perform repeated decompression operations that can drive CPU usage extremely high and allocate massive intermediate buffers, potentially exhausting memory and causing process crashes or host instability. The issue has been fixed by limiting the number of allowed chained encodings to 5 in urllib3 2.6.0.What the disclosure says (summary)
- A vulnerability was assigned CVE-2025-66418 and classified as a high-severity denial-of-service issue.
- Affected versions: urllib3 >= 1.24 and < 2.6.0.
- Impact: Excessive CPU and memory consumption when processing crafted responses that specify a very long chain of content encodings.
- Fix: Introduced a hard-coded limit (5) on the maximum number of chained content encodings; code now raises a decode error when the chain length exceeds the limit.
- Remediation path: Upgrade to urllib3 2.6.0 or later. If upgrading is not immediately possible, use defensive measures such as disabling automatic content decoding and validating the
Content-Encodingheader before reading response bodies.
Technical overview
How chained content encoding works
HTTP response bodies can be encoded using one or more compression or transformation algorithms. TheContent-Encoding header lists the encodings applied in sequence. A client that receives a response must apply decoders in reverse order to reconstruct the original payload. Typical uses are simple (single encodings such as gzip), but the HTTP standard allows chaining multiple encodings.Where the defect appears
The decoding pipeline in vulnerable urllib3 versions parsed theContent-Encoding header into a list of decoders and applied them sequentially with no upper bound on the number of entries. A malicious server can therefore advertise a very long encoding list (for example hundreds or thousands of entries), causing the client to perform repeated decompression passes and allocate large intermediate buffers, which leads to:- Prolonged CPU-intensive decompression operations;
- Large memory allocations during decompression, potentially exceeding available memory;
- Blocking or crashing of the requesting process, and cascading service failures if the process serves other workloads.
The fix
The maintainers implemented a defensive limit by adding a maximum allowed count for chained encodings (max_decode_links = 5). If a response advertises more than five content encodings, urllib3 raises a decoding exception instead of attempting to decode the entire chain. Tests were added to cover the failure case and ensure regressions do not reintroduce the problem.Who and what is affected
Direct impacts
- Any Python application that imports a vulnerable version of urllib3 and performs HTTP requests with automatic decoding enabled.
- Applications that fetch data from untrusted endpoints, third-party APIs, or that perform web scraping where responses are not fully controlled.
Indirect impacts (downstream libraries and ecosystems)
- Higher-level libraries that bundle or depend on urllib3 (for example, Requests or other HTTP clients) may be affected either directly or indirectly depending on how they vendor or pin urllib3.
- Cloud SDKs, automation tools, CI/CD agents, containerized services, monitoring agents, and other software components that perform HTTP requests can be vulnerable.
- Packaged applications on Windows (executables bundling a Python runtime and dependencies) may contain vulnerable urllib3 copies embedded inside the application bundle.
Distribution and package manager considerations
- Linux distributions that ship system-level Python packages (for example, Debian/Ubuntu) may need to produce distribution updates; some distributions list vulnerable binary packages and will follow with fixes or backports.
- Embedded or vendor-supplied application installers for Windows can embed older versions of urllib3; those packages will remain vulnerable until vendors release updated installers or guidance.
Severity, exploitability and real-world risk
- Severity: categorized as High (CVSSv4 score reported around 8.9) because the vulnerability is remotely exploitable and can cause high-impact availability loss.
- Exploitability: the attack vector is network-based — a remote server can trigger the issue simply by sending a crafted HTTP response. This means any code that issues requests to attacker-controlled servers, or to servers that could be compromised, is exposed.
- Known active exploitation: at the time of writing there were no widely reported public exploit scripts weaponizing the flaw that target production systems, but the attack is conceptually simple to implement and straightforward to test.
- Practical risk profile: high for applications that connect to untrusted endpoints (e.g., web crawlers, open API clients, integrations that accept user-supplied URLs). Lower risk for clients that only connect to tightly controlled, trusted backend services where server behavior is vetted.
Immediate mitigation steps for Windows system administrators and developers
- Identify affected environments and installations.
- Search for installed urllib3 versions in all Python environments:
- python -c "import urllib3, sys; print(sys.executable, urllib3.version)"
- pip show urllib3
- For virtual environments and embedded runtimes (standalone EXEs, installers), inspect bundled packages.
- Use dependency scanners (pip-audit, pipdeptree, Safety, OS vendor advisories) to list packages that depend on urllib3.
- Search for installed urllib3 versions in all Python environments:
- Upgrade urllib3 where possible.
- For pip-managed environments: pip install --upgrade "urllib3>=2.6.0"
- For environments where a strict version is required, install at least urllib3==2.6.0 and run tests.
- If immediate upgrade is not feasible, apply defensive code changes.
- Disable automatic response content decoding and perform explicit, validated decoding:
- Use
preload_content=Falsewhen creating HTTP response objects (or equivalent in higher-level wrappers) and inspectresp.headers["content-encoding"]to ensure it contains a small, expected number of encodings before consuming the response body.
- Use
- Implement timeouts and memory limits for request handlers to reduce blast radius.
- Disable automatic response content decoding and perform explicit, validated decoding:
- Patch container images and rebuild.
- Rebuild any Docker/OCI images that include vulnerable urllib3 and redeploy.
- Update CI/CD pipelines to use updated base images or to run dependency upgrades.
- Coordinate with vendors.
- If using third-party Windows applications that likely embed Python and urllib3, contact the vendor for guidance and request updated packages.
- Watch for vendor security bulletins and distro advisories for official updates and backports.
- Add runtime protections.
- Enforce per-process resource limits where possible (container memory limits, Windows job objects, service process isolation).
- Add circuit-breakers in HTTP client code that fail fast on suspicious responses.
Longer-term recommendations (software supply chain hardening)
- Enforce dependency monitoring in CI: add pip-audit or other SCA tools to detect and fail builds including known vulnerable versions of urllib3.
- Implement pinned dependency policies with regular scheduled upgrades; avoid permanent pinning to old versions without a maintenance plan.
- Maintain an internal vulnerability advisory channel and a standard operating procedure for dependency updates (test, stage, deploy).
- For applications distributed on Windows with bundled runtimes, provide incremental hotfix/patch paths and clear instructions for customers to update.
- Review integration points that accept user-provided URLs or content; treat any external resource as untrusted and validate server responses before decoding large payloads.
Developer guidance: code-level hardening
- Prefer explicit decoding and limit chain length:
- When reading responses from untrusted hosts, set
preload_content=False(or equivalent) to avoid automatic pipeline decoding. - Inspect
resp.headers.get("content-encoding", "")and parse it safely. Reject responses where the header contains more than a small, acceptable number of encodings. - For libraries that wrap urllib3 (e.g., higher-level HTTP clients), add validation layers so that the lower-level library is protected regardless of the caller’s behavior.
- When reading responses from untrusted hosts, set
- Example checklist for library maintainers:
- Ensure your package’s dependency specifications allow upgrading to urllib3 2.6.0 (update install_requires or constraints files).
- Add unit tests that simulate responses with excessive
Content-Encodingchains and verify that your package fails safely. - If you vendor urllib3 inside your project, update the vendored copy and publish a patch release.
Why this matters to Windows users and sysadmins
Many Windows environments run Python-based tooling — automation scripts, backup utilities, monitoring agents, cloud CLI tools, and developer utilities. Some of these are packaged as self-contained Windows executables (pyinstaller, py2exe, or custom installers) that embed a Python interpreter and a frozen dependency set. That means:- Even if the system Python is updated, embedded or vendor-supplied runtimes may remain vulnerable until the vendor issues an update.
- Windows services and scheduled tasks that perform recurring HTTP requests to external endpoints can be remotely targeted by malicious servers that reply with crafted responses to induce resource exhaustion.
- Containerized Windows workloads and Windows nodes running containerized Linux workloads can be vulnerable if images include vulnerable urllib3 packages.
Testing and detection: practical commands and scans
- Check installed urllib3 version in a specific environment:
- Activate the virtualenv (if any) and run:
- python -c "import urllib3; print(urllib3.version)"
- Or:
- pip show urllib3
- Activate the virtualenv (if any) and run:
- Identify indirect dependencies:
- pipdeptree --reverse --packages urllib3
- pip-audit or other SCA tools can list known vulnerable transitive dependencies.
- CI integration:
- Add a step in CI to run
pip-auditor use a dependency scanning action to fail builds if urllib3 < 2.6.0 is present.
- Add a step in CI to run
- Windows-specific checks:
- Enumerate installed Python distributions (system Python, Anaconda, application-bundled runtimes).
- Search installation directories for
urllib3packages orurllib3folders inside application installations.
Caveats, open questions, and cautions
- While the vulnerability is straightforward and fixable by upgrading to urllib3 2.6.0, real-world mitigation complexity depends on how urllib3 is consumed in your environment. Vendor-bundled or frozen packages require vendor updates.
- Some higher-level libraries may still be pinned to old urllib3 versions for compatibility; in those cases, coordination with maintainers or upgrades of those libraries will be necessary.
- There was no widespread, confirmed public exploit observed at the time this article was written; however, the simplicity of the attack (a crafted response header) means security teams should treat the issue with urgency.
- Official advisories from some platform vendors may lag; check vendor channels for distro-specific patches and guidance.
Checklist: what to do now (prioritized)
- Inventory: locate every Python runtime and package set on your Windows estate and identify urllib3 versions.
- Upgrade: where feasible, upgrade urllib3 to 2.6.0 or later and rebuild any application bundles or container images.
- Patch vendors: for packaged third-party apps, contact vendors and apply their security patches as they are released.
- Apply mitigations: temporarily disable automatic decoding for untrusted endpoints or validate
Content-Encodingheader length before reading the body. - Monitor: add detection to logging and monitoring to identify unusual spikes in CPU/memory correlated with HTTP requests.
- Harden CI: block builds that include vulnerable urllib3 versions and add dependency scanning to deployment pipelines.
Final analysis: strengths of the fix and residual risk
The maintainers implemented a clear, simple, and test-covered defense: limiting the number of chained encodings to 5 and raising an explicit error for longer chains. That change is minimal and low-risk for typical usage patterns because legitimate servers rarely apply more than a couple of encodings.Strengths:
- The fix is small and deterministic, reducing chances of regressions.
- Tests added ensure the new behavior is validated.
- Upgrading to 2.6.0 is a straightforward remediation path for most pip-managed environments.
- The principal risk is operational: many deployments will remain vulnerable until every Python runtime — including vendor-supplied and embedded copies — is updated.
- Applications that accept user-supplied URLs or integrate with third-party content are exposed to potential DoS from malicious endpoints.
- Supply-chain and compatibility issues (libraries pinned to older urllib3 versions) may delay fixes in production environments.
The bottom line: treat CVE-2025-66418 as a high-priority dependency update. For most teams, the appropriate immediate response is to upgrade urllib3 to 2.6.0 across environments, rebuild and redeploy bundles and images, and, where that is not instantly possible, apply conservative runtime checks to avoid blindly decoding untrusted responses. Early detection, rapid remediation, and tighter supply-chain controls will limit the operational impact of this straightforward but dangerous resource-exhaustion vulnerability.
Source: MSRC Security Update Guide - Microsoft Security Response Center