CVE-2015-0220
NoneCVSS
—
EPSS
3.1%
Published
Jan 16, 2015
CISA due date
—
Cloudanix analysis
A security flaw in a common web development tool could let an attacker steal user account credentials or display fraudulent content by tricking users into clicking a specially crafted link.
- Exploitation
- Requires User Interaction
- Attacker needs
- User Interaction
- Complexity
- Low
- Impact
- Data Exposure
- Component
- Web Framework
- Class
- XSS
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
The `is_safe_url` function in vulnerable Django versions fails to properly sanitize leading whitespace in URLs. This allows an attacker to craft a URL with a leading whitespace character (like a newline) followed by a `javascript:` payload. The validation function incorrectly approves this URL as safe, leading to an open redirect that can be escalated to a cross-site scripting (XSS) attack. When a user is redirected to such a URL, the browser executes the embedded JavaScript in the context of the user's session on the vulnerable website, compromising client-side integrity.
Why it matters to the business
This vulnerability allows attackers to impersonate users and take over their accounts by stealing session cookies. It can also be used to deface web pages, redirect users to malicious websites for phishing attacks, or trick them into revealing sensitive information. Successful exploitation erodes user trust, can lead to the compromise of user data, and may result in reputational damage and potential compliance violations.
How an attack unfolds
An attacker identifies a Django-based website that uses a vulnerable version and has a feature that redirects users based on a URL parameter (e.g., a 'next' parameter after login). The attacker crafts a malicious link containing this parameter, setting its value to a URL with a leading newline character followed by a `javascript:` payload (e.g., `https://example.com/login?next=\njavascript:steal_cookie()`). The attacker then distributes this link to victims via phishing emails or social media. When a victim clicks the link, their browser navigates to the site. The Django application's `is_safe_url` check improperly validates the malicious redirect URL as safe. After the user performs an action like logging in, the application issues a redirect to the `javascript:` URL, causing the victim's browser to execute the attacker's script. This script can then steal session tokens and send them to an attacker-controlled server, enabling account takeover.
How to fix it
To remediate this vulnerability, upgrade Django to a patched version. Per the advisory, users of version 1.4 should upgrade to 1.4.18 or later, users of 1.6 should upgrade to 1.6.10 or later, and users of 1.7 should upgrade to 1.7.3 or later. If an immediate upgrade is not feasible, a temporary mitigation involves creating a custom URL validation function or middleware that strips leading whitespace from the URL before it is processed by `is_safe_url`.
How to confirm the fix worked
To validate the fix, manually test any redirect functionality within the application. Identify a URL parameter that controls redirects (e.g., `next`, `redirect_to`). Craft a URL using this parameter with a payload containing a URL-encoded newline (`%0A`) followed by a `javascript:` URI, such as `https://<your-app>/login?next=%0Ajavascript:alert(document.domain)`. If the application is patched, it should treat the URL as invalid and prevent the redirect, or encode the output so the script does not execute. If a JavaScript alert box appears, the application remains vulnerable.
Typical attack path
- Attacker identifies a vulnerable Django application with a redirect mechanism.
- Attacker crafts a malicious URL with a parameter pointing to a `javascript:` URI preceded by a whitespace character (e.g., `?next=%0Ajavascript:alert(1)`).
- Attacker sends the malicious link to a victim through phishing or another social engineering method.
- The victim clicks the link and is taken to the vulnerable web application.
- The application's URL validation function incorrectly flags the malicious URL as safe.
- The application redirects the user's browser to the malicious `javascript:` URI.
- The victim's browser executes the attacker's script, leading to session hijacking or other client-side attacks.
How to detect it
To detect potential exploitation, review web server (e.g., Nginx, Apache) and application logs for incoming HTTP requests. Search for requests where URL query parameters, particularly common redirect parameters like `next`, `redirect`, `goto`, or `continue`, contain a URL-encoded whitespace character (`%0A`, `%0D`, `+`, etc.) immediately followed by the string `javascript:`. Correlate any findings with the source IP and check for subsequent anomalous activity associated with the targeted user accounts.
- ?next=%0Ajavascript:
- &next=%0Ajavascript:
- ?next=%0Djavascript:
- &next=%0Djavascript:
- ?redirect=%0Ajavascript:
- &redirect=%0Ajavascript:
- ?redirect=%0Djavascript:
- &redirect=%0Djavascript:
- ?continue=%0Ajavascript:
- &continue=%0Ajavascript:
What your security team should do
- Immediately identify all applications using vulnerable Django versions and prioritize upgrading them to 1.4.18, 1.6.10, 1.7.3, or a more recent stable release.
- Review application source code for any custom URL validation logic to ensure it is not susceptible to similar whitespace-related bypasses.
- Configure Web Application Firewall (WAF) rules to detect and block requests containing URL parameters with `javascript:` payloads, especially when combined with encoded whitespace characters, as a defense-in-depth measure.
The record
The django.util.http.is_safe_url function in Django before 1.4.18, 1.6.x before 1.6.10, and 1.7.x before 1.7.3 does not properly handle leading whitespaces, which allows remote attackers to conduct cross-site scripting (XSS) attacks via a crafted URL, related to redirect URLs, as demonstrated by a "\njavascript:" URL.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| PyPI | django | 0 | 1.4.18 |
| PyPI | django | 1.6 | 1.6.10 |
| PyPI | django | 1.6.0 | 1.6.10 |
| PyPI | django | 1.7 | 1.7.3 |
| PyPI | django | 1.7.0 | 1.7.3 |
| Debian:11 | python-django | 0 | 1.7.1-1.1 |
| Debian:12 | python-django | 0 | 1.7.1-1.1 |
| Debian:13 | python-django | 0 | 1.7.1-1.1 |
| Debian:6.0 | python-django | 0 | 1.2.3-3+squeeze12 |
| Debian:7 | python-django | 0 | 1.4.5-1+deb7u9 |
| Mageia:4 | python-django | 0 | 1.5.9-1.1.mga4 |
| Mageia:4 | python-django14 | 0 | 1.4.18-1.1.mga4 |
| Ubuntu:14.04:LTS | python-django | 0 | 1.6.1-2ubuntu0.6 |
| pypi | Django | 1.6 | No fix |
| pypi | Django | 1.7 | No fix |
Related vulnerabilities
- GHSA-8p8v-wh79-9r56 Django vulnerable to Uncontrolled Resource Consumption Also affects django
- GHSA-mjgh-79qc-68w3 Django has a Race Condition vulnerability Also affects django
- CVE-2026-25673 An issue was discovered in 6.0 before 6.0.3, 5.2 before 5.2.12, and 4.2 before 4.2.29. Also affects django
- CVE-2026-25674 An issue was discovered in 6.0 before 6.0.3, 5.2 before 5.2.12, and 4.2 before 4.2.29. Also affects django
- GHSA-6426-9fv3-65x8 Django has an SQL Injection issue Also affects django
- GHSA-gvg8-93h5-g6qq Django has an SQL Injection issue Also affects django
- GHSA-2mcm-79hx-8fxw Django has Observable Timing Discrepancy Also affects django
- GHSA-33mw-q7rj-mjwj Django has Inefficient Algorithmic Complexity Also affects django