Cloudanix VulnDB

CVE-2015-0219

None

CVSS

—

EPSS

7.0%

Published

Jan 16, 2015

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

Some older Django websites can be tricked into accepting a fake user identity sent in a specially named request header.

Exploit Available
Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Low
Impact
Privilege Gain
Component
Web Framework
Class
Authentication Bypass
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

Django versions before 1.4.18, 1.6.10, and 1.7.3 can incorrectly treat HTTP headers containing underscores as equivalent to headers containing dashes after WSGI/CGI normalization. Because many authentication and authorization integrations trust reverse-proxy-supplied headers such as user identity or role headers, a remote unauthenticated attacker may be able to inject a spoofed header like X-Auth_User that is normalized into the same application variable as X-Auth-User. The direct impact is integrity compromise of request metadata, which can lead to authentication bypass or privilege confusion in applications that rely on trusted inbound headers.

Why it matters to the business

Applications using affected Django versions may allow users to impersonate other users or gain access intended only for authenticated users if the application trusts identity headers from a proxy or single sign-on layer. The risk is highest for internet-facing Django deployments behind reverse proxies, SSO gateways, or middleware that pass user identity through HTTP headers. Although this issue is old and not in the CISA KEV catalog, public exploit knowledge exists and legacy Django deployments remain exposed if they were never upgraded.

How an attack unfolds

An attacker sends a crafted HTTP request directly to a vulnerable Django application or through an intermediary that does not block underscore-containing headers. Instead of sending the legitimate trusted header name with a dash, the attacker sends a visually similar header using an underscore, such as X-Auth_User. During WSGI normalization, both the dashed and underscored forms can map to the same request metadata key, such as HTTP_X_AUTH_USER. If the application, middleware, or authentication integration uses that metadata key as proof of identity, the attacker-controlled value may be accepted as if it came from a trusted proxy or authentication gateway. The attacker can then access protected functionality as another user or with elevated application privileges, depending on how the trusted header is used.

How to fix it

Upgrade Django to a fixed release: 1.4.18 or later for the 1.4 branch, 1.6.10 or later for the 1.6 branch, or 1.7.3 or later for the 1.7 branch. Prefer upgrading to a currently supported Django release because all affected branches are long end-of-life. As defense in depth, configure front-end proxies and web servers to reject or drop request headers containing underscores, and ensure the application is not reachable directly except through the trusted proxy path. Review authentication middleware and application code for any use of request.META, HTTP_* variables, REMOTE_USER-style headers, X-Auth-User, X-Forwarded-User, or other identity-bearing headers, and only trust those values when they are set by a controlled upstream component after untrusted client-supplied versions have been stripped.

How to confirm the fix worked

Confirm the deployed Django version is 1.4.18, 1.6.10, 1.7.3, or newer, and ideally a currently supported release. Verify package inventories, lockfiles, virtual environments, and running application images rather than relying only on source repositories. Test the running service by sending a request with an underscore-containing identity header, such as X-Auth_User, and confirm it is rejected, removed by the proxy, or ignored by application authentication logic. Confirm reverse proxies and web servers are configured to drop headers with underscores and that direct network access to the Django application server is blocked from untrusted networks. Regression-test any header-based SSO or proxy-authentication flows after patching to ensure legitimate trusted headers still work only through the intended proxy path.

Typical attack path

  1. Identify a Django application using an affected version prior to 1.4.18, 1.6.10, or 1.7.3.
  2. Determine whether the application trusts HTTP headers for authentication, user identity, roles, tenant selection, or authorization decisions.
  3. Send requests containing underscore-based variants of trusted headers, such as X-Auth_User instead of X-Auth-User.
  4. Observe whether the application treats the spoofed header value as authenticated or privileged request metadata.
  5. Use the accepted spoofed identity or authorization context to access protected pages, APIs, or administrative functions.

How to detect it

To determine whether exploitation already occurred, review web server, reverse proxy, WAF, load balancer, and application access logs for HTTP request headers containing underscores, especially identity-related headers. Focus on requests to login-protected APIs, administrative pages, account management paths, or actions that changed data. Look for unusual combinations where a request lacks a normal authenticated session but includes headers such as X-Auth_User, X-Forwarded_User, X-Remote_User, Remote_User, or other organization-specific identity headers with underscores. In application logs, correlate suspicious requests with unexpected authenticated usernames, sudden privilege changes, anomalous user switching from the same source IP, or protected endpoint access without the expected SSO/session artifacts. If packet captures, WAF event bodies, or full-fidelity HTTP telemetry are available, search raw headers because many access log formats do not record request headers by default. Also review proxy configuration and logs for evidence that the backend was reachable directly, since direct-to-backend access materially increases exploitation likelihood.

  • X-Auth_User:
  • X-Forwarded_User:
  • X-Remote_User:
  • X-User_Name:
  • X-Authenticated_User:
  • Remote_User:
  • HTTP_X_AUTH_USER
  • HTTP_X_FORWARDED_USER
  • HTTP_X_REMOTE_USER
  • HTTP_REMOTE_USER
  • _User:
  • _USER

What your security team should do

  • Prioritize remediation for any internet-facing or externally reachable Django application that uses proxy-based, SSO-based, or header-based authentication.
  • Upgrade affected Django installations to fixed or supported versions; treat legacy 1.4, 1.6, and 1.7 branches as unsupported technical debt requiring migration.
  • Configure reverse proxies, load balancers, and web servers to reject or strip HTTP request headers containing underscores before traffic reaches Django.
  • Review application and middleware code for trust in HTTP_* request metadata and remove reliance on client-controllable headers for authentication or authorization.
  • Block direct access to application backends so requests must pass through the hardened proxy or authentication gateway.
  • Search historical access logs for underscore-containing identity or authorization headers and investigate any successful requests to protected endpoints using those headers.
  • Add automated tests and WAF/SIEM detections for suspicious headers such as X-Auth_User, X-Forwarded_User, X-Remote_User, and similar underscore variants.

The record

Django before 1.4.18, 1.6.x before 1.6.10, and 1.7.x before 1.7.3 allows remote attackers to spoof WSGI headers by using an _ (underscore) character instead of a - (dash) character in an HTTP header, as demonstrated by an X-Auth_User header.

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
SUSE:Enterprise Storage 1.0 python-Django 0 1.6.11-4.1
Ubuntu:14.04:LTS python-django 0 1.6.1-2ubuntu0.6
openSUSE:Tumbleweed python-bjoern 0 1.4.2-1.23
openSUSE:Tumbleweed python-bjoern 0 3.2.2-1.10
pypi Django 1.6 No fix
pypi Django 1.7 No fix

Related vulnerabilities