CVE-2017-7234
Medium · 6.1CVSS
6.1
EPSS
1.8%
Published
Apr 4, 2017
CISA due date
—
Cloudanix analysis
A flaw in the website's software could allow an attacker to create special links that look safe but secretly redirect users to malicious websites for phishing attacks.
- Exploitation
- Requires User Interaction
- Attacker needs
- User Interaction
- Complexity
- Low
- Impact
- Other
- Component
- Web Framework
- Class
- Open Redirect
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
The vulnerability exists in the `django.views.static.serve()` view, which is intended for serving files during development. A maliciously crafted URL can abuse this view to cause an HTTP redirect to an arbitrary external domain. The server itself is not compromised, but its trusted domain is used to initiate a redirect to a potentially malicious location, lending it an unearned air of legitimacy.
Why it matters to the business
This open redirect vulnerability can be used to facilitate phishing campaigns against a company's users. Attackers can craft links that appear to originate from the trusted website but redirect users to malicious sites designed to steal credentials, distribute malware, or commit fraud. Successful exploitation erodes user trust, can lead to financial loss for customers, and causes significant reputational damage to the brand.
How an attack unfolds
An attacker first identifies a Django website improperly using the `django.views.static.serve()` view in a production environment. The attacker then crafts a special URL that targets this view but includes an external, attacker-controlled domain in the path. This malicious link is distributed to victims through phishing emails, social media, or other channels, masquerading as a legitimate link to the trusted site. When a victim clicks the link, their browser sends a request to the vulnerable Django server. The server processes the request and issues an HTTP 3xx redirect response, pointing the user's browser to the attacker's domain. The victim's browser automatically follows this redirect, landing them on the malicious site where they may be phished for credentials or served malware.
How to fix it
The primary remediation is to upgrade Django to a patched version: Django 1.10.7 or later, 1.9.13 or later, or 1.8.18 or later. As a fundamental best practice, you should not use `django.views.static.serve()` in a production environment. This view is inefficient and insecure for production use. Configure a dedicated web server such as Nginx or Apache to serve static files, or use a cloud storage service and CDN. Ensure your production `settings.py` has `DEBUG = False` and your `urls.py` does not route to `django.views.static.serve()`.
How to confirm the fix worked
To validate the fix, first confirm that the Django version in your environment is patched by running `python -m django --version` or checking your dependency management file. Second, audit your project's `urls.py` files to ensure that `django.views.static.serve` is not used in any URL patterns for the production environment. You can also perform a negative test by attempting to craft a URL with a double-slash prefix (e.g., `https://[your-site]/[static-path-prefix]//example.com`) and verifying that it does not redirect to `example.com`, but instead results in a 404 Not Found error.
Typical attack path
- Attacker identifies a Django site using the vulnerable `django.views.static.serve` view in production.
- Attacker crafts a malicious URL containing a protocol-relative path (e.g., `//malicious.com`) targeting the static view.
- Attacker distributes the URL to victims via a phishing campaign.
- Victim clicks the trusted-looking link.
- The vulnerable Django application returns an HTTP 302 redirect to the attacker's malicious site.
- Victim's browser is redirected to the malicious site, which can be used for phishing or malware delivery.
How to detect it
To detect potential exploitation, security teams should analyze web server access logs (e.g., from Nginx, Apache, or other reverse proxies) and application logs. Look for HTTP GET requests to URL paths associated with static file serving that result in a 301 or 302 redirect. The key indicator of an exploitation attempt is a request path that begins with a double forward slash (`//`) or double backslash (`\\`) immediately following the static directory prefix, which tricks the server into generating a redirect to an external, protocol-relative URL.
- GET /static//<external_domain>
- GET /media//<external_domain>
What your security team should do
- Immediately upgrade all affected Django applications to a patched version (1.10.7+, 1.9.13+, or 1.8.18+).
- Audit all Django projects to identify and remove any use of `django.views.static.serve` in production URL configurations, replacing it with a proper static file serving strategy.
- Scan web server access logs for request patterns indicative of exploitation attempts, such as requests to static paths containing `//` or `\\` followed by an external domain.
The record
A maliciously crafted URL to a Django (1.10 before 1.10.7, 1.9 before 1.9.13, and 1.8 before 1.8.18) site using the ``django.views.static.serve()`` view could redirect to any other domain, aka an open redirect vulnerability.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| PyPI | django | 1.10 | 1.10.7 |
| PyPI | django | 1.8 | 1.8.18 |
| PyPI | django | 1.9 | 1.9.13 |
| Alpine:v3.10 | py-django | 0 | 1.10.7-r0 |
| Alpine:v3.11 | py3-django | 0 | 1.10.7-r0 |
| Alpine:v3.12 | py3-django | 0 | 1.10.7-r0 |
| Alpine:v3.2 | py-django | 0 | 1.8.18-r0 |
| Alpine:v3.3 | py-django | 0 | 1.8.18-r0 |
| Alpine:v3.4 | py-django | 0 | 1.8.18-r0 |
| Alpine:v3.5 | py-django | 0 | 1.8.18-r0 |
| Alpine:v3.6 | py-django | 0 | 1.10.7-r0 |
| Alpine:v3.7 | py-django | 0 | 1.10.7-r0 |
| Alpine:v3.8 | py-django | 0 | 1.10.7-r0 |
| Alpine:v3.9 | py-django | 0 | 1.10.7-r0 |
| Debian:11 | python-django | 0 | 1:1.10.7-1 |
| Debian:12 | python-django | 0 | 1:1.10.7-1 |
| Debian:13 | python-django | 0 | 1:1.10.7-1 |
| Debian:7 | python-django | 0 | 1.4.22-1+deb7u3 |
| Debian:8 | python-django | 0 | 1.7.11-1+deb8u2 |
| Mageia:5 | python-django | 0 | 1.8.16-1.1.mga5 |
| SUSE:OpenStack Cloud 6 | python-Django | 0 | 1.8.19-3.6.1 |
| SUSE:OpenStack Cloud 7 | python-Django | 0 | 1.8.19-3.4.1 |
| SUSE:Package Hub 12 | python-Django | 0 | 1.11.10-5.1 |
| SUSE:Package Hub 12 SP1 | python-Django | 0 | 1.11.15-2.1 |
| Ubuntu:14.04:LTS | python-django | 0 | 1.6.11-0ubuntu1.1 |
| Ubuntu:16.04:LTS | python-django | 0 | 1.8.7-1ubuntu5.5 |
| openSUSE:Tumbleweed | python-Django | 0 | 3.2.7-2.3 |
| openSUSE:Tumbleweed | python-Django | 0 | 4.2.11-2.1 |
| openSUSE:Tumbleweed | python-Django4 | 0 | 4.2.14-1.1 |
| openSUSE:Tumbleweed | python-Django6 | 0 | 6.0-1.1 |
| pypi | Django | 1.10 | No fix |
| pypi | Django | 1.8 | No fix |
| pypi | Django | 1.9 | 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