CVE-2015-2317
NoneCVSS
—
EPSS
5.0%
Published
Mar 25, 2015
CISA due date
—
Cloudanix analysis
A security flaw in a common web development tool could allow an attacker to craft a malicious link that, when clicked, can steal a user's session information or take over their account.
- Exploitation
- Requires User Interaction
- Attacker needs
- User Interaction
- Complexity
- Low
- Impact
- Data Tampering
- Component
- Web Framework
- Class
- XSS
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
A flaw in the `utils.http.is_safe_url` function in Django fails to properly sanitize URLs containing control characters. This allows an attacker to craft a URL that bypasses the safety check, leading to an open redirect. This can be escalated to a cross-site scripting (XSS) attack by using a `javascript:` URI, enabling the execution of arbitrary script code in the context of the victim's browser session on the affected domain.
Why it matters to the business
Exploitation of this vulnerability can lead to the compromise of user accounts, allowing attackers to steal sensitive information, perform unauthorized actions on behalf of the user, and erode trust in the application. Successful attacks can result in reputational damage, credential theft through phishing, and the potential for further propagation of attacks within the user base. This undermines the integrity of the user's interaction with the web service.
How an attack unfolds
An attacker identifies a Django application that uses a vulnerable version of the `is_safe_url` function to validate user-supplied URLs for redirection, typically via a URL parameter like `next` or `redirect_to`. The attacker crafts a malicious link containing a control character (e.g., a backspace `\x08`) to bypass the validation, followed by a `javascript:` payload. This link is then sent to a victim through a phishing email or other social engineering vector. When the victim clicks the link, the vulnerable application incorrectly validates the URL as safe and redirects the user. The browser then executes the attacker's JavaScript payload, which can be used to steal session cookies, scrape data from the page, or redirect the user to a malicious site.
How to fix it
To remediate this vulnerability, upgrade Django to a patched version. The following versions contain the fix: - Django 1.4.x users should upgrade to version 1.4.20 or later. - Django 1.6.x users should upgrade to version 1.6.11 or later. - Django 1.7.x users should upgrade to version 1.7.7 or later. - Django 1.8.x users should upgrade to version 1.8c1 or later. If an immediate upgrade is not feasible, developers should perform strict, whitelist-based validation on any user-provided URL before passing it to a redirect function, ensuring that no unexpected characters or URL schemes are allowed.
How to confirm the fix worked
To confirm if your application is vulnerable, first check the installed Django version using `python -m django --version` or by inspecting your project's dependency files (e.g., `requirements.txt`). Compare the version against the fixed versions (1.4.20, 1.6.11, 1.7.7, 1.8c1). Additionally, you can use a software composition analysis (SCA) tool to automatically detect vulnerable dependencies. For manual validation in a safe test environment, identify a redirect parameter in your application and attempt to inject a payload like `?next=%08javascript:alert(document.domain)`. A vulnerable application will execute the alert, while a patched one will not.
Typical attack path
- Attacker identifies a vulnerable Django application that uses URL parameters for redirection.
- Attacker crafts a malicious URL with a `javascript:` payload obfuscated by a control character (e.g., `?next=\x08javascript:alert(1)`).
- Attacker distributes the malicious link to potential victims via phishing or other social engineering methods.
- A victim clicks the link, sending a request to the vulnerable application.
- The application's `is_safe_url` check is bypassed, and it issues a redirect 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 exploitation attempts, security teams should search web server access logs, load balancer logs, and Web Application Firewall (WAF) logs for HTTP requests containing URL-encoded control characters. Specifically, look for patterns where common redirect parameters (e.g., `next`, `redirect`, `continue`, `url`) are followed by an encoded control character (like `%08` for backspace) and the `javascript:` scheme. The presence of such patterns is a strong indicator of an attempt to exploit this vulnerability.
- next=%08javascript:
- redirect=%08javascript:
- continue=%08javascript:
- url=%08javascript:
- next=%09javascript:
- redirect=%09javascript:
What your security team should do
- Immediately prioritize upgrading all applications using vulnerable Django versions to a patched release.
- Deploy software composition analysis (SCA) tools across all development pipelines to proactively identify and flag vulnerable open-source dependencies.
- Configure Web Application Firewalls (WAFs) to detect and block requests containing control characters and `javascript:` schemes in URL parameters, which can serve as a virtual patch.
The record
The utils.http.is_safe_url function in Django before 1.4.20, 1.5.x, 1.6.x before 1.6.11, 1.7.x before 1.7.7, and 1.8.x before 1.8c1 does not properly validate URLs, which allows remote attackers to conduct cross-site scripting (XSS) attacks via a control character in a URL, as demonstrated by a \x08javascript: URL.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| PyPI | django | 0 | 1.4.20 |
| PyPI | django | 1.5 | 1.6.11 |
| PyPI | django | 1.7 | 1.7.7 |
| PyPI | django | 1.8a1 | 1.8c1 |
| Debian:11 | python-django | 0 | 1.7.7-1 |
| Debian:12 | python-django | 0 | 1.7.7-1 |
| Debian:13 | python-django | 0 | 1.7.7-1 |
| Debian:6.0 | python-django | 0 | 1.2.3-3+squeeze13 |
| Debian:7 | python-django | 0 | 1.4.5-1+deb7u11 |
| Mageia:4 | python-django | 0 | 1.5.9-1.2.mga4 |
| Mageia:4 | python-django14 | 0 | 1.4.20-1.mga4 |
| SUSE:Enterprise Storage 1.0 | python-Django | 0 | 1.6.11-4.1 |
| Ubuntu:14.04:LTS | python-django | 0 | 1.6.1-2ubuntu0.8 |
| pypi | Django | 1.5 | No fix |
| pypi | Django | 1.7 | No fix |
| pypi | Django | 1.8a1 | 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