CVE-2021-3733 Overview
A Regular Expression Denial of Service (ReDoS) vulnerability exists in Python's urllib library, specifically within the AbstractBasicAuthHandler class. An attacker who controls a malicious HTTP server that an HTTP client connects to can trigger this vulnerability by sending a specially crafted payload during an authentication request. This flaw primarily threatens application availability by causing excessive CPU consumption during regex processing.
Critical Impact
Applications using Python's urllib for HTTP authentication can be rendered unresponsive when connecting to malicious servers that exploit the inefficient regex pattern in the authentication handler.
Affected Products
- Python (multiple versions including 3.10.0)
- Red Hat Enterprise Linux 8.x and EUS versions
- Red Hat CodeReady Linux Builder 8.0
- Fedora 33, 34, 35, 36
- NetApp Management Services for Element Software and NetApp HCI
- NetApp ONTAP Select Deploy Administration Utility
- NetApp SolidFire, Enterprise SDS & HCI Storage Node
Discovery Timeline
- 2022-03-10 - CVE-2021-3733 published to NVD
- 2025-11-03 - Last updated in NVD database
Technical Details for CVE-2021-3733
Vulnerability Analysis
The vulnerability resides in the regular expression used by Python's AbstractBasicAuthHandler class within the urllib.request module. The flaw occurs because the regex pattern used to parse HTTP authentication headers contains an inefficient character class that can lead to catastrophic backtracking when processing maliciously crafted input.
When an HTTP client using urllib connects to a malicious server, the server can send a specially crafted WWW-Authenticate header that triggers exponential regex evaluation time. This causes the client application to hang or consume excessive CPU resources, effectively creating a denial of service condition.
The vulnerability is exploitable over the network without requiring any privileges on the victim system. An attacker only needs to control or compromise an HTTP server that the victim's Python application connects to. The attack does not require user interaction once the application initiates a connection to the malicious endpoint.
Root Cause
The root cause is an inefficient regular expression pattern in the urllib.request module. The original regex pattern '([^ \\t]+)' for matching the authentication scheme did not properly exclude comma characters from the character class. This omission allowed specially crafted input strings to cause excessive backtracking in the regex engine, leading to exponential time complexity during pattern matching.
Attack Vector
The attack is conducted over the network by a malicious HTTP server. When a Python HTTP client using urllib attempts to authenticate with a server controlled by an attacker, the server responds with a malformed WWW-Authenticate header containing a payload designed to trigger catastrophic regex backtracking. The client application becomes unresponsive while attempting to parse the malicious header, resulting in denial of service.
# Security patch in Lib/urllib/request.py - bpo-43075: Fix ReDoS in urllib AbstractBasicAuthHandler (GH-24391)
# (single quotes are a violation of the RFC, but appear in the wild)
rx = re.compile('(?:^|,)' # start of the string or ','
'[ \t]*' # optional whitespaces
- '([^ \t]+)' # scheme like "Basic"
+ '([^ \t,]+)' # scheme like "Basic"
'[ \t]+' # mandatory whitespaces
# realm=xxx
# realm='xxx'
Source: GitHub CPython Commit
Detection Methods for CVE-2021-3733
Indicators of Compromise
- Unusual CPU spikes in Python processes making HTTP authentication requests
- Application hangs or unresponsiveness when connecting to external HTTP services
- Network connections to unknown or suspicious HTTP servers that remain open for extended periods
- Log entries indicating failed or stalled authentication attempts
Detection Strategies
- Monitor Python application performance for anomalous CPU usage during HTTP operations
- Implement request timeouts for HTTP client connections to detect hanging requests
- Audit network traffic for connections to untrusted HTTP endpoints that respond with unusual WWW-Authenticate headers
- Review application logs for authentication handler timeout events or exceptions
Monitoring Recommendations
- Configure alerting on Python process CPU utilization thresholds exceeding normal baselines
- Implement network monitoring to detect long-lived HTTP connections that may indicate ReDoS exploitation
- Deploy application performance monitoring (APM) tools to track urllib request latency
- Enable verbose logging for HTTP authentication events to identify malicious server responses
How to Mitigate CVE-2021-3733
Immediate Actions Required
- Update Python to a patched version that includes the fix for bpo-43075
- Implement connection timeouts for all HTTP client operations using urllib
- Review and restrict network access to untrusted HTTP endpoints
- Consider using alternative HTTP libraries with proper input validation for critical applications
Patch Information
The vulnerability has been addressed in Python through PR #24391. The fix modifies the regex pattern in Lib/urllib/request.py to properly exclude comma characters from the scheme matching character class, changing '([^ \\t]+)' to '([^ \\t,]+)'. This prevents the catastrophic backtracking condition.
Patches are available through:
- Python Issue Tracker (bpo-43075)
- Ubuntu Security Advisory
- NetApp Security Advisory NTAP-20220407-0001
- Red Hat Enterprise Linux updates for affected versions
Workarounds
- Implement strict timeout values for all HTTP requests using urllib to prevent indefinite hangs
- Use firewall rules to restrict outbound HTTP connections to known trusted endpoints only
- Deploy a proxy server to inspect and sanitize HTTP authentication headers before reaching Python applications
- Consider temporarily switching to alternative HTTP libraries like requests with proper timeout configuration
# Configuration example - Setting connection timeouts in Python applications
# Add socket timeout before urllib operations
import socket
socket.setdefaulttimeout(30) # 30 second global timeout
# Or configure per-request timeout
import urllib.request
urllib.request.urlopen(url, timeout=30)
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


