CVE-2023-45803 Overview
CVE-2023-45803 is an information disclosure vulnerability in urllib3, a widely-used HTTP client library for Python. The vulnerability occurs when urllib3 fails to remove the HTTP request body during redirect responses (301, 302, or 303) when the request method changes from a body-accepting method (like POST) to GET. According to HTTP RFCs and observed behavior in other major HTTP clients like curl and web browsers, the request body should be stripped during such redirects. This improper handling can lead to sensitive data being inadvertently sent to unintended destinations.
Critical Impact
Sensitive data submitted in HTTP request bodies (such as form data, credentials, or JSON payloads) may be exposed to malicious or compromised redirect targets when a trusted service redirects using 301, 302, or 303 status codes.
Affected Products
- Python urllib3 versions prior to 1.26.18
- Python urllib3 versions 2.x prior to 2.0.7
- Fedora 38 (via bundled urllib3 package)
Discovery Timeline
- October 17, 2023 - CVE-2023-45803 published to NVD
- November 3, 2025 - Last updated in NVD database
Technical Details for CVE-2023-45803
Vulnerability Analysis
This information disclosure vulnerability stems from urllib3's improper handling of HTTP redirect responses. When a client sends a POST request with sensitive data in the body and receives a 301, 302, or 303 redirect response, HTTP specifications require that the subsequent request method be changed to GET. The GET method, by definition, should not contain a request body. However, vulnerable versions of urllib3 failed to strip the request body during this method transition, causing the original body content to be sent along with the redirected GET request.
The exploitability requires a specific scenario: a previously trusted service must become compromised and configured to redirect requests to a malicious endpoint. While this represents a moderate barrier to exploitation, the potential for credential or sensitive data leakage makes this a significant concern for applications processing confidential information.
Root Cause
The root cause lies in urllib3's redirect handling logic, which did not properly implement the RFC 9110 specification for HTTP semantics. The library failed to clear the request body when automatically following redirects that resulted in a method change from POST (or other body-accepting methods) to GET. This behavior contradicts the HTTP standard, which specifies that GET requests should not have a message body that affects request semantics.
Attack Vector
For this vulnerability to be exploited, two conditions must be met:
- The application must use urllib3 and submit sensitive information in the HTTP request body (such as form data, authentication tokens, or JSON payloads)
- Either the origin service becomes compromised and starts issuing 301/302/303 redirects to a malicious peer, or the redirected-to service itself becomes compromised
The attack vector requires adjacent network access and involves a compromised trusted service redirecting legitimate requests to an attacker-controlled endpoint, where the sensitive request body data can be captured.
# Security patch in dummyserver/handlers.py - Bring 2.0.7 & 1.26.18 to main (#3161)
def headers(self, request: httputil.HTTPServerRequest) -> Response:
return Response(json.dumps(dict(request.headers)))
+ def headers_and_params(self, request: httputil.HTTPServerRequest) -> Response:
+ params = request_params(request)
+ return Response(
+ json.dumps({"headers": dict(request.headers), "params": params})
+ )
def multi_headers(self, request: httputil.HTTPServerRequest) -> Response:
return Response(json.dumps({"headers": list(request.headers.get_all())}))
Source: GitHub Commit
Detection Methods for CVE-2023-45803
Indicators of Compromise
- Unexpected HTTP request bodies appearing in GET requests following redirects
- Sensitive data (credentials, tokens, form data) being transmitted to unexpected endpoints
- Network traffic showing POST to GET redirect chains that retain body content
- Log entries indicating redirects from trusted services to unfamiliar destinations
Detection Strategies
- Implement network monitoring to detect HTTP redirects (301, 302, 303) that result in GET requests containing body data
- Audit Python application dependencies using pip list or dependency scanning tools to identify vulnerable urllib3 versions
- Deploy application-layer firewalls to inspect and alert on unexpected body content in redirected requests
- Use software composition analysis (SCA) tools to continuously monitor for vulnerable urllib3 versions in your codebase
Monitoring Recommendations
- Enable detailed HTTP logging in applications to capture redirect chains and request body transmission
- Monitor for unexpected outbound connections following redirect responses from trusted services
- Implement alerting on SSL/TLS connections to unfamiliar endpoints during redirect handling
- Review application logs for 301, 302, or 303 response codes from services that typically should not redirect
How to Mitigate CVE-2023-45803
Immediate Actions Required
- Upgrade urllib3 to version 1.26.18 or later for 1.x branch users
- Upgrade urllib3 to version 2.0.7 or later for 2.x branch users
- Audit all Python applications and dependencies that may bundle urllib3
- Review application code for sensitive data transmission patterns that could be affected
Patch Information
The vulnerability has been addressed in urllib3 versions 1.26.18 and 2.0.7. The fix ensures that HTTP request bodies are properly stripped when redirect responses (301, 302, 303) cause a method change to GET.
+2.0.7 (2023-10-17)
+==================
+
+* Made body stripped from HTTP requests changing the request method to GET after HTTP 303 "See Other" redirect responses.
2.0.6 (2023-10-02)
==================
Source: GitHub Commit
For detailed information, refer to the GitHub Security Advisory and RFC 9110 documentation.
Workarounds
- Disable automatic redirects for services not expected to respond with redirects by setting redirects=False
- Handle 301, 302, and 303 redirects manually by explicitly stripping the HTTP request body before following
- Implement application-level validation to ensure sensitive data is not retransmitted on redirects
- Consider using a wrapper function to intercept redirect responses and sanitize request bodies
# Configuration example - Disable automatic redirects in Python urllib3
# In your Python code, configure urllib3 to not follow redirects:
#
# import urllib3
# http = urllib3.PoolManager(redirect=False)
# response = http.request('POST', 'https://example.com/api', body=sensitive_data)
#
# Then manually handle redirect responses:
# if response.status in (301, 302, 303):
# # Follow redirect without the original body
# new_url = response.headers.get('Location')
# response = http.request('GET', new_url)
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


