Overview
CVE-2007-0405 describes a vulnerability in Django 0.95 where the AuthenticationMiddleware's LazyUser caches the authenticated user across requests. This caching can enable an attacker using a valid session to assume the privileges of a different user, effectively bypassing per-request authentication checks and enabling unauthorized access. In practice, such caching can lead to cross-request identity leakage and potential resource misuse under an attacker\'s context, contributing to Unrestricted Resource Consumption through actions performed on behalf of another user. This guide references CVE-2007-0405 to illustrate a concrete historical instance where per-request authentication state was not properly isolated, underscoring the importance of per-request correctness in Django security models.
In practice, the bug can allow cross-request identity leakage that enables abuse of resources on behalf of another user. A real-world attacker could trigger resource-intensive actions (database queries, API calls) under a different user context, resulting in unrestricted resource consumption and potential denial of service or data exposure. The risk is not just privilege elevation in isolation; it translates into tangible misuse of server resources when authenticated operations are carried out under unintended identities.
Remediation steps include upgrading to a patched Django release that fixes the LazyUser caching, auditing any custom middleware that caches user identity, and ensuring per-request authentication state without cross-request caches. Validate with tests that request.user matches the true authenticated user for every request, and remove any module-level caches that store user data to prevent cross-request leakage.
Affected Versions
Django 0.95
Code Fix Example
Django API Security Remediation
VULNERABLE PATTERN (global cache):
# Simulated global cache that persists across requests
_cached_user = None
class User:
def __init__(self, uid):
self.id = uid
def _load_user_from_session(session):
user_id = session.get('user_id')
return User(user_id) if user_id is not None else None
def vulnerable_middleware_factory(get_response):
def middleware(request):
global _cached_user
if _cached_user is not None:
request['user'] = _cached_user
else:
user = _load_user_from_session(request['session'])
_cached_user = user
request['user'] = user
return get_response(request)
return middleware
# FIX PATTERN:
def fixed_middleware_factory(get_response):
def middleware(request):
request['user'] = _load_user_from_session(request['session'])
return get_response(request)
return middleware