GHSA-pf96-p4fj-6566
HTTPX2: Conflicting Content-Length and Transfer-Encoding headers can be auto-generated
Quick fix
GHSA-pf96-p4fj-6566 — httpx2: upgrade to the fixed version with the command below.
pip install --upgrade 'httpx2>=2.11.0'Details
### Summary
HTTPX2 can automatically add a `Content-Length` header to a request that already contains a caller-supplied `Transfer-Encoding` header. The resulting HTTP/1.1 request contains both framing headers, which can create an ambiguous message boundary and enable request smuggling or connection desynchronization when processed by intermediaries that disagree about which header takes precedence.
### Details
When a request body has a known size, HTTPX2's content encoder returns a default `Content-Length`. `Request._prepare()` applies each default header with `setdefault()`, which only checks whether that same header is already present. It does not check whether the mutually exclusive `Transfer-Encoding` header is present.
For example:
```python import httpx2
request = httpx2.Request( "POST", "http://example.com/", headers={"Transfer-Encoding": "chunked"}, content=b"test 123", )
print(request.headers) ```
The request contains both:
```text Transfer-Encoding: chunked Content-Length: 8 ```
On an HTTP/1.1 connection, the body is serialized using chunked transfer coding while both headers are sent on the wire. This violates HTTP message-framing requirements. Fixed-size byte, JSON, form, and known-length multipart bodies can reach the affected path.
Streaming bodies with an explicit `Content-Length` are not affected in current HTTPX2 releases because the automatically generated `Transfer-Encoding` is already suppressed in that direction.
### Impact
An attacker may be able to use the conflicting framing headers as a request-smuggling or desynchronization primitive. Exploitation requires an application to pass attacker-controlled request framing headers and associated body data to HTTPX2, use HTTP/1.1, and communicate through a proxy or origin that accepts conflicting headers and interprets them differently from another hop.
Depending on the downstream infrastructure, successful exploitation could interfere with requests sharing a persistent connection, bypass front-end routing or authorization decisions, or poison responses or caches. Applications that do not forward attacker-controlled `Transfer-Encoding` headers are not directly exposed.
### Mitigation
Upgrade to HTTPX2 `2.11.0` or later. Patched versions treat `Content-Length` and `Transfer-Encoding` as mutually exclusive when applying automatically generated request headers.
If upgrading is not immediately possible, remove `Transfer-Encoding` and other hop-by-hop framing headers from untrusted input before constructing outbound requests. Applications acting as proxies should derive outbound framing from the body rather than forwarding inbound `Content-Length` or `Transfer-Encoding` headers.
Are you affected?
Enter the version of the package you're using.
Affected packages
References
- https://github.com/pydantic/httpx2/security/advisories/GHSA-pf96-p4fj-6566[WEB]
- https://nvd.nist.gov/vuln/detail/CVE-2026-84380[ADVISORY]
- https://github.com/pydantic/httpx2/pull/1137[WEB]
- https://github.com/pydantic/httpx2/commit/829b93a2393212996f613e635261f777d9ec6eab[WEB]
- https://github.com/pydantic/httpx2[PACKAGE]
- https://github.com/pydantic/httpx2/releases/tag/v2.11.0[WEB]