CVE-2021-32052 Overview
CVE-2021-32052 is an HTTP Response Splitting vulnerability affecting Django web framework versions 2.2 before 2.2.22, 3.1 before 3.1.10, and 3.2 before 3.2.2 when used with Python 3.9.5 or later. The vulnerability exists in the URLValidator class which fails to prohibit newlines and tabs in URL values. When applications use URL values containing newline characters in HTTP responses, attackers can inject malicious HTTP headers, potentially leading to cross-site scripting attacks or cache poisoning.
Critical Impact
Applications using Django's URLValidator with unsanitized URL values in HTTP responses may be vulnerable to header injection attacks, enabling cross-site scripting (XSS) or response manipulation. Django's core HttpResponse class is unaffected as it already prohibits newlines in HTTP headers.
Affected Products
- Django 2.2.x versions before 2.2.22
- Django 3.1.x versions before 3.1.10
- Django 3.2.x versions before 3.2.2
- Python 3.9.5 and later (when used with affected Django versions)
- Fedora 34 (bundled Django packages)
Discovery Timeline
- 2021-05-06 - CVE-2021-32052 published to NVD
- 2021-05-06 - Django Project releases security patches (versions 2.2.22, 3.1.10, 3.2.2)
- 2024-11-21 - Last updated in NVD database
Technical Details for CVE-2021-32052
Vulnerability Analysis
This vulnerability is classified under CWE-79 (Improper Neutralization of Input During Web Page Generation), though it primarily manifests as an HTTP Response Splitting issue. The root problem lies in Django's URLValidator class which validates URLs but does not reject URLs containing newline (\n, \r) or tab (\t) characters. When Python 3.9.5 introduced stricter URL parsing, certain behaviors changed that exposed this weakness in Django's validation logic.
The vulnerability requires specific conditions to be exploitable: an application must accept user-controlled URL values validated through URLValidator (outside of URLField form fields which have additional protections) and subsequently include those values in HTTP response headers or body without additional sanitization.
Root Cause
The vulnerability stems from insufficient input validation in Django's URLValidator class. While the validator checks for proper URL structure and protocol schemes, it does not strip or reject control characters like carriage returns (\r), line feeds (\n), and tabs (\t). These characters are significant in HTTP protocol as they can terminate headers and start new ones, enabling header injection.
The URLField form field is not affected because it performs additional sanitization. However, developers using URLValidator directly or storing validated URLs without using URLField may inadvertently create vulnerable code paths. Django's HttpResponse class provides built-in protection by rejecting newlines in headers, but this doesn't protect all use cases such as redirects using user-supplied URLs or custom response generation.
Attack Vector
The attack requires network access and user interaction. An attacker crafts a malicious URL containing encoded newline characters. When this URL passes through Django's URLValidator and is subsequently used in an HTTP response context, the injected characters can split the HTTP response. This enables various attacks including injecting arbitrary HTTP headers for XSS payloads, setting malicious cookies, or manipulating caching behavior.
For example, an attacker could submit a URL like https://example.com%0d%0aSet-Cookie:%20malicious=value which, when improperly handled, could inject a Set-Cookie header into the response.
Detection Methods for CVE-2021-32052
Indicators of Compromise
- HTTP response logs showing unexpected header values or malformed responses
- Application logs containing URLs with URL-encoded newline sequences (%0d%0a, %0a, %0d)
- Evidence of cross-site scripting attacks originating from header injection
- Cache servers returning unexpected content for legitimate URLs
Detection Strategies
- Review application code for direct usage of URLValidator outside of form fields
- Scan web server access logs for URL parameters containing encoded newline characters (%0d, %0a, %0D, %0A)
- Implement web application firewall (WAF) rules to detect and block CRLF injection attempts
- Audit Django applications for custom response handling that includes user-supplied URLs
Monitoring Recommendations
- Configure log analysis to alert on URLs containing CRLF sequences in request parameters
- Monitor for anomalous HTTP response sizes or unexpected headers in reverse proxy logs
- Implement runtime application self-protection (RASP) to detect header injection attempts
- Set up alerts for Django applications running vulnerable version ranges
How to Mitigate CVE-2021-32052
Immediate Actions Required
- Upgrade Django to patched versions: 2.2.22+, 3.1.10+, or 3.2.2+ immediately
- Audit all code paths using URLValidator directly for potential exposure
- Implement input sanitization to strip newlines and tabs from URL values before use
- Review and restrict URL-based redirects to prevent open redirect exploitation
Patch Information
Django released security patches on May 6, 2021, addressing this vulnerability. The fix ensures that URLValidator properly rejects URLs containing newline and tab characters. Organizations should upgrade to Django 2.2.22, 3.1.10, or 3.2.2 (or later versions). Detailed information is available in the Django Security Release Documentation and the Django Weblog Security Release Update. Fedora users should update their packages as noted in the Fedora Package Announcement.
Workarounds
- Use URLField form fields instead of URLValidator directly where possible, as they include additional sanitization
- Implement custom validation to strip or reject newline and tab characters before URL processing
- Configure web application firewalls to block requests containing CRLF sequences in URL parameters
- Ensure HTTP responses use Django's HttpResponse class which already blocks newlines in headers
# Upgrade Django to patched version
pip install --upgrade 'Django>=3.2.2'
# Verify installed version
python -c "import django; print(django.VERSION)"
# For requirements.txt, update the Django version constraint
# Django>=3.2.2
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

