CVE-2026-1502 Overview
CVE-2026-1502 is an HTTP Response Splitting vulnerability in Python's http.client module where CR/LF (Carriage Return/Line Feed) bytes were not properly rejected by HTTP client proxy tunnel headers or host parameters. This input validation flaw allows attackers to inject malicious header content when applications use Python's HTTP client for proxy tunnel connections.
Critical Impact
Attackers with privileged access can inject arbitrary HTTP headers through improperly validated tunnel host names or header values, potentially leading to HTTP response splitting, cache poisoning, or cross-site scripting attacks.
Affected Products
- Python CPython (HTTP client library)
- Applications using Python's http.client module for proxy tunneling
- Systems utilizing Python's CONNECT proxy tunnel functionality
Discovery Timeline
- 2026-04-10 - CVE CVE-2026-1502 published to NVD
- 2026-04-13 - Last updated in NVD database
Technical Details for CVE-2026-1502
Vulnerability Analysis
The vulnerability exists in Python's http.client module, specifically in the _tunnel() method responsible for establishing HTTP proxy tunnel connections. When applications configure proxy tunneling via the set_tunnel() method, the tunnel host and custom headers were not validated for CR/LF control characters before being incorporated into the CONNECT request.
HTTP Response Splitting attacks exploit the fact that HTTP headers are delimited by CRLF sequences (\r\n). By injecting these control characters into header values or hostnames, an attacker can terminate the current header and inject arbitrary headers or even complete HTTP responses. This can lead to cache poisoning, session hijacking, or cross-site scripting depending on how intermediate proxies and caches handle the malformed responses.
The vulnerability requires privileged access and user interaction to exploit, as the attacker must control input that reaches the tunnel configuration. However, in scenarios where applications accept user-provided proxy configurations or tunnel headers, this flaw presents a significant injection risk.
Root Cause
The root cause is insufficient input validation in the _tunnel() method of Lib/http/client.py. Prior to the patch, the code directly encoded and concatenated tunnel headers without checking for illegal characters. The tunnel host was similarly not validated against the _contains_disallowed_url_pchar_re regex pattern that checks for control characters.
The header construction code previously used:
headers.append(f"{header}: {value}\r\n".encode("latin-1"))
This allowed header names and values containing CR/LF sequences to be passed through without rejection, enabling HTTP header injection.
Attack Vector
The attack is network-based and targets applications that allow external input to influence HTTP proxy tunnel configurations. An attacker with elevated privileges who can control tunnel header values or hostnames can inject CRLF sequences to:
- Terminate the current header prematurely
- Inject additional malicious headers
- Potentially inject a complete HTTP response body in cache poisoning scenarios
The following security patch demonstrates the fix implemented in Python's http.client module:
return ip
def _tunnel(self):
+ if _contains_disallowed_url_pchar_re.search(self._tunnel_host):
+ raise ValueError('Tunnel host can\'t contain control characters %r'
+ % (self._tunnel_host,))
connect = b"CONNECT %s:%d %s\r\n" % (
self._wrap_ipv6(self._tunnel_host.encode("idna")),
self._tunnel_port,
self._http_vsn_str.encode("ascii"))
headers = [connect]
for header, value in self._tunnel_headers.items():
- headers.append(f"{header}: {value}\r\n".encode("latin-1"))
+ header_bytes = header.encode("latin-1")
+ value_bytes = value.encode("latin-1")
+ if not _is_legal_header_name(header_bytes):
+ raise ValueError('Invalid header name %r' % (header_bytes,))
+ if _is_illegal_header_value(value_bytes):
+ raise ValueError('Invalid header value %r' % (value_bytes,))
+ headers.append(b"%s: %s\r\n" % (header_bytes, value_bytes))
headers.append(b"\r\n")
# Making a single send() call instead of one per line encourages
# the host OS to use a more optimal packet size instead of
Source: GitHub Commit Security Update
Detection Methods for CVE-2026-1502
Indicators of Compromise
- Unexpected CR (\r) or LF (\n) characters in HTTP proxy tunnel request logs
- Malformed CONNECT requests in proxy server logs containing injected headers
- Applications throwing ValueError exceptions after patching with messages about invalid header names or control characters
Detection Strategies
- Monitor HTTP proxy logs for CONNECT requests containing unusual header patterns or multiple CRLF sequences
- Implement input validation logging to detect attempts to pass control characters to set_tunnel() calls
- Review application code for user-controlled input reaching HTTPConnection.set_tunnel() method calls
- Deploy web application firewalls (WAF) rules to detect CRLF injection patterns in proxy configurations
Monitoring Recommendations
- Enable verbose logging on proxy servers to capture full CONNECT request headers
- Configure intrusion detection systems to alert on CRLF sequences in HTTP header values
- Audit Python application dependencies to identify usage of vulnerable http.client proxy tunnel functionality
How to Mitigate CVE-2026-1502
Immediate Actions Required
- Update Python to a patched version that includes the security fix from commit 05ed7ce7ae9e17c23a04085b2539fe6d6d3cef69
- Review applications for usage of HTTPConnection.set_tunnel() with user-controlled input
- Implement application-level input validation to reject CR/LF characters in any data passed to tunnel configurations
- Consider using higher-level HTTP libraries with built-in header validation
Patch Information
The vulnerability has been addressed in Python CPython through the security patch referenced in GitHub Commit Security Update. The fix adds validation checks using _contains_disallowed_url_pchar_re, _is_legal_header_name(), and _is_illegal_header_value() functions to reject control characters before constructing tunnel requests.
For additional details, see the GitHub Issue Discussion, GitHub Pull Request Review, and the Python Security Announcement Thread.
Workarounds
- Sanitize all user input before passing to set_tunnel() by stripping or rejecting CR/LF characters
- Use allowlist validation for tunnel host names, permitting only expected hostname patterns
- Implement strict header value validation at the application layer using regex patterns to reject control characters
# Example Python input validation before calling set_tunnel()
# Add to application code as a workaround until patching is possible
import re
def validate_tunnel_input(value):
if re.search(r'[\r\n]', value):
raise ValueError(f"Invalid input: control characters detected")
return value
# Usage: validate_tunnel_input(user_provided_host)
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

