CVE-2026-84379 Overview
CVE-2026-84379 is a header injection vulnerability [CWE-93] in HTTPX2, a next-generation HTTP client for Python maintained by Pydantic. The flaw resides in FileField.render_headers() within src/httpx2/httpx2/_multipart.py. The function interpolates attacker-controlled content_type values and custom headers from the files= tuple directly into multipart/form-data part headers. HTTPX2 performs no validation of header names or values, allowing carriage return (CR) or line feed (LF) characters to terminate part headers or inject new ones. Versions prior to 2.11.0 are affected.
Critical Impact
Attackers who control multipart file metadata can inject arbitrary part headers, potentially altering part semantics or bypassing header-based checks in downstream multipart parsers.
Affected Products
- HTTPX2 versions prior to 2.11.0
- Python applications using files= tuple parameters with untrusted content_type or header inputs
- Downstream services parsing multipart/form-data produced by vulnerable HTTPX2 clients
Discovery Timeline
- 2026-09-02 - CVE-2026-84379 published to NVD
- 2026-09-02 - Last updated in NVD database
- Fixed in v2.11.0 - Patch released via GitHub Pull Request #1142
Technical Details for CVE-2026-84379
Vulnerability Analysis
HTTPX2 accepts multipart file uploads through the files= parameter, which supports three-element (filename, content, content_type) tuples and four-element (filename, content, content_type, headers) tuples. The FileField.render_headers() method concatenates these values into the raw part header block without applying any character-level sanitization.
RFC 7230 restricts header names to a specific token set and prohibits control characters within header values. HTTPX2 violates this contract by trusting caller-supplied strings. When an application forwards untrusted user input into these fields, attackers can inject CRLF sequences (\r\n) to break out of the intended header context.
Injected headers may override Content-Disposition, redirect part names, or terminate the header block early so that attacker payload bytes are treated as additional headers. Downstream multipart parsers then process the forged headers as legitimate, which can bypass filename filters, MIME-type allowlists, or size checks that inspect declared headers.
Root Cause
The root cause is missing input validation on header names and values passed through the files= tuple interface. The vulnerable code path in _multipart.py did not enforce the RFC 7230 token grammar for header names and did not reject control characters (\\x00-\\x08, \\x0a-\\x1f, \\x7f) inside header values before rendering the part header block.
Attack Vector
Exploitation requires an application that forwards attacker-controlled data into the content_type argument or the custom headers dictionary of an HTTPX2 multipart upload. The attacker submits a content_type string containing \r\n followed by a forged header. HTTPX2 emits this content verbatim into the outbound request. The upstream server treats the injected line as a real part header, altering how the part is interpreted.
# Patch from src/httpx2/httpx2/_multipart.py (v2.11.0)
_HTML5_FORM_ENCODING_REPLACEMENTS = {'"': "%22", "\\": "\\\\"}
_HTML5_FORM_ENCODING_REPLACEMENTS.update({chr(c): f"%{c:02X}" for c in range(0x1F + 1) if c != 0x1B})
_HTML5_FORM_ENCODING_RE = re.compile(r"|".join([re.escape(c) for c in _HTML5_FORM_ENCODING_REPLACEMENTS.keys()]))
_HEADER_NAME_RE = re.compile(r"[!#$%&'*+\-.^_`|~0-9A-Za-z]+")
_FORBIDDEN_HEADER_VALUE_CHARS_RE = re.compile(r"[\\x00-\\x08\\x0a-\\x1f\\x7f]")
Source: GitHub Commit de96d810. The patch adds _HEADER_NAME_RE to enforce the RFC 7230 token grammar and _FORBIDDEN_HEADER_VALUE_CHARS_RE to reject control characters in header values.
Detection Methods for CVE-2026-84379
Indicators of Compromise
- Outbound multipart/form-data requests containing raw \r\n sequences inside Content-Type or custom part headers.
- Server-side multipart parsers logging duplicate or unexpected Content-Disposition headers within a single part.
- Application logs showing user-supplied file metadata containing control characters or embedded header names such as X-, Content-Length, or Content-Disposition.
Detection Strategies
- Perform static analysis on Python codebases to locate httpx2 calls that pass untrusted variables to the content_type position or headers dictionary of files= tuples.
- Inspect the installed HTTPX2 version with pip show httpx2 across build environments and container images.
- Deploy web application firewall or reverse proxy rules that reject multipart parts whose header block contains CR/LF within values.
Monitoring Recommendations
- Instrument outbound HTTP client wrappers to log and reject multipart parts containing control characters in metadata.
- Alert on downstream multipart parsers that report malformed or duplicated part headers on ingress from internal services.
- Track HTTPX2 dependency updates in software composition analysis (SCA) tooling to confirm the 2.11.0 upgrade has propagated.
How to Mitigate CVE-2026-84379
Immediate Actions Required
- Upgrade HTTPX2 to version 2.11.0 or later across all Python services, build pipelines, and container images.
- Audit application code for any path that assigns user input to the content_type field or custom headers dictionary in files= tuples.
- Validate and reject user-supplied MIME types and header values that contain CR, LF, NUL, or other control characters before invoking HTTPX2.
Patch Information
The fix ships in HTTPX2 v2.11.0. It introduces _HEADER_NAME_RE to validate header names against the RFC 7230 token grammar and _FORBIDDEN_HEADER_VALUE_CHARS_RE to reject forbidden control characters in header values. See the GitHub Security Advisory GHSA-h4x7-gw46-3wm6 for full details.
Workarounds
- Wrap HTTPX2 calls with a helper that strips or rejects CR, LF, and other control characters from content_type and custom header values before request construction.
- Constrain MIME types to a strict allowlist (for example image/png, application/pdf) instead of accepting free-form strings.
- Terminate TLS at a reverse proxy that normalizes and validates multipart headers before forwarding requests to backend parsers.
# Upgrade to the patched release
pip install --upgrade 'httpx2>=2.11.0'
# Verify the installed version
pip show httpx2 | grep -i version
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.