Skip to content

GHSA-pf96-p4fj-6566 CVE-2026-84380 PYSEC-2026-3849

HTTPX2: Conflicting Content-Length and Transfer-Encoding headers can be auto-generated

Medium PyPI
Severity
5.6 / 10
Medium · CVSS 3.1
Exploit chance (EPSS)
0.22%
Chance of exploitation in the next 30 days. Higher than 12.73% of scored vulnerabilities.
Known exploited
No
Not in CISA's catalog
Weakness
CWE-444 Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
Fix
2.11.0
Upgrade httpx2 to this version or later

Description

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:

import httpx2

request = httpx2.Request(
    "POST",
    "http://example.com/",
    headers={"Transfer-Encoding": "chunked"},
    content=b"test 123",
)

print(request.headers)

The request contains both:

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.

Affected versions

PyPI

PackageVulnerableFixed in
httpx2
< 2.11.0
2.11.0
httpx2
< 2.11.0
2.11.0

How to fix

Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.

httpx2 PyPI → 2.11.0

pip
pip install --upgrade "httpx2>=2.11.0"
poetry
poetry add "httpx2>=2.11.0"
uv
uv add "httpx2>=2.11.0"

Severity breakdown

CVSS 3.1 5.6

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L

Attack vector
Network
Attack complexity
High
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
Low

Weakness

CWE-444: Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')

The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.

How to prevent it
  • Implementation: Use a web server that employs a strict HTTP parsing procedure, such as Apache [REF-433].
  • Implementation: Use only SSL communication.
  • Implementation: Terminate the client session after each request.
  • System Configuration: Turn all pages to non-cacheable.

References

Timeline

  1. Published
  2. Last updated by the source
  3. Latest EPSS score
AdvisorySeverityWhy it's related
GHSA-8xx6-hgc6-gc2m
HTTPX2: Streaming response decompression does not bound peak memory (decompression amplification)
High Also affects httpx2
GHSA-7mj9-2mp8-4m2p
HTTPX2: Secure WebSocket traffic sent without TLS through SOCKS proxies
High Also affects httpx2
GHSA-h4x7-gw46-3wm6
HTTPX2: Multipart part header injection via unvalidated file Content-Type and custom headers
Medium Also affects httpx2
GHSA-f2fp-rgf2-35cp
HTTPX2: Quadratic SSE line buffering can cause CPU denial of service
Medium Also affects httpx2
EEF-CVE-2026-114216
Chunk extensions accept bare LF and CR, enabling request smuggling in Bandit
Not rated yet Same weakness, CWE-444
RUSTSEC-2026-0388
Pingora HTTP/2 :authority and Host header mismatch enables cache poisoning and host-based access control bypass
Not rated yet Same weakness, CWE-444
GHSA-pqxq-w44r-73xw
AIOHTTP: Pure-Python parser request smuggling
Medium Same weakness, CWE-444
GHSA-rv87-ccxw-8ggf
Microsoft Security Advisory CVE-2026-88092 - ASP.NET Core Security Feature Bypass Vulnerability
Critical Same weakness, CWE-444
Is this in your code?

MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.

Check your repos with MergeHarbor