CVE-2025-57804 Overview
CVE-2025-57804 is an HTTP request smuggling vulnerability in h2, a pure-Python implementation of the HTTP/2 protocol stack. Versions prior to 4.3.0 accept carriage return and line feed (CRLF) characters inside HTTP/2 header names and values. When an upstream server or proxy downgrades HTTP/2 requests to HTTP/1.1 without revalidating headers, attackers can inject CRLF sequences to split a single request into two. This enables request smuggling, cache poisoning, and bypass of front-end security controls. The issue is classified under CWE-93: Improper Neutralization of CRLF Sequences and was patched in h2 version 4.3.0.
Critical Impact
Attackers can smuggle HTTP requests through HTTP/2-to-HTTP/1.1 downgrade paths, bypassing authentication, WAF, and access control checks at front-end proxies.
Affected Products
- h2 Python library versions prior to 4.3.0
- Python HTTP/2 servers and clients depending on vulnerable h2 releases (for example, hypercorn, hyper-h2 consumers)
- Debian LTS distributions shipping vulnerable python-hyper-h2 packages
Discovery Timeline
- 2025-08-25 - CVE-2025-57804 published to the National Vulnerability Database
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2025-57804
Vulnerability Analysis
The h2 library parses HTTP/2 HEADERS frames and passes the decoded header names and values to the application. HTTP/2 uses a binary framing layer, so CRLF has no structural meaning inside a header value at the wire level. However, downstream systems frequently downgrade HTTP/2 to HTTP/1.1 when proxying to legacy origin servers.
In HTTP/1.1, CRLF terminates headers and separates the header block from the body. If h2 accepts a header value containing \r\n, that sequence survives the downgrade and is interpreted as a header boundary by the HTTP/1.1 parser. An attacker crafts a header value that injects a new Content-Length, Transfer-Encoding, or entire second request, desynchronizing the connection.
This primitive enables classic HTTP request smuggling: bypassing front-end authentication, poisoning shared caches, hijacking sessions of subsequent users on the same backend connection, and pivoting internal services.
Root Cause
The root cause is insufficient character validation in the header sanitization logic of src/h2/utilities.py. The pre-patch code permitted headers to contain any bytes except a small denylist. The patch removes the denylist approach and enforces a strict allowlist consistent with RFC 7230 field-name and field-value grammar, rejecting \r, \n, \\x00, and other control characters outright.
Attack Vector
The attacker sends an HTTP/2 request to a front-end proxy that forwards to an HTTP/1.1 backend. A header value contains embedded \r\n sequences forming a smuggled request. The backend parses the smuggled portion as a separate request queued after the legitimate one, executing under the trust context of the front-end.
# Source: https://github.com/python-hyper/h2/commit/035e9899f95e3709af098f578bfc3cd302298e3a
# Security patch in src/h2/utilities.py — removes the permissive denylist
# so header validation is enforced through a stricter allowlist elsewhere.
SIGIL = ord(b":")
INFORMATIONAL_START = ord(b"1")
-HEADER_UNPERMITTED_CHARACTERS = frozenset([
- b"\r",
- b"\n",
- b"\\x00",
-])
-
# A set of headers that are hop-by-hop or connection-specific and thus
# forbidden in HTTP/2. This list comes from RFC 7540 § 8.1.2.2.
Detection Methods for CVE-2025-57804
Indicators of Compromise
- HTTP/2 HEADERS frames containing raw 0x0D (CR) or 0x0A (LF) bytes within header name or value fields
- Backend access logs showing unexpected request pairs or duplicate Content-Length and Transfer-Encoding headers on the same connection
- Cache entries associated with URLs that were never requested by legitimate clients
- Anomalous request boundaries logged by front-end proxies immediately preceding backend 400-series errors
Detection Strategies
- Deploy HTTP/2-aware inspection at the reverse proxy layer to flag CRLF or NUL bytes in decoded HPACK headers before forwarding
- Enable strict header validation in downstream HTTP/1.1 parsers and alert on parser desynchronization errors
- Perform software composition analysis (SCA) on Python projects to enumerate versions of the h2 package below 4.3.0
Monitoring Recommendations
- Ingest reverse proxy and application logs into a centralized platform and correlate 400/408/502 spikes with client identifiers
- Monitor for unexpected requests attributed to authenticated sessions that did not originate from the client
- Track cache hit anomalies and unusual variance in Vary header responses that may indicate cache poisoning
How to Mitigate CVE-2025-57804
Immediate Actions Required
- Upgrade the h2 library to version 4.3.0 or later across all Python services and dependent frameworks
- Rebuild and redeploy container images that bundle the h2 package to eliminate vulnerable copies from runtime
- On Debian LTS systems, apply the updates announced in the Debian LTS Announcement
- Audit reverse proxies and API gateways to confirm they normalize or reject CRLF in headers when downgrading HTTP/2 to HTTP/1.1
Patch Information
The fix is included in h2 4.3.0. Review the GitHub Security Advisory GHSA-847f-9342-265h and the upstream commit for the code change that tightens header character validation.
Workarounds
- Terminate HTTP/2 at a proxy that enforces strict RFC 9113 header field validation and blocks control characters before requests reach the Python service
- Disable HTTP/2-to-HTTP/1.1 downgrade paths where feasible and prefer end-to-end HTTP/2 or HTTP/1.1
- Add an application-layer middleware that rejects any header whose value contains bytes outside the RFC 7230 field-vchar range
# Upgrade the vulnerable package with pip
pip install --upgrade "h2>=4.3.0"
# Verify the installed version
python -c "import h2; print(h2.__version__)"
# Debian / Ubuntu: apply distribution updates
sudo apt-get update && sudo apt-get install --only-upgrade python3-h2
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

