Overview
Broken Object Level Authorization (BOLA) occurs when per-object access checks are bypassed because user identity is reused across requests. CVE-2007-0405 documents a Django 0.95 issue where the AuthenticationMiddleware's LazyUser implementation cached the username across requests, enabling an authenticated user to gain the privileges of another user.
Exploitation in practice involved the server reusing a cached username for authorization decisions across requests. An attacker could authenticate as one user and then interact with resources (or perform admin-level actions) that should have been restricted to a different user, simply due to the stale username used by the check.
Remediation involves removing cross-request caching and relying on per-request user data from Django's AuthenticationMiddleware. Ensure authorization checks use request.user and the actual object owner, not a cached username. Upgrade to a Django version patched after 0.95 and verify there is no global caching of identity in custom middleware, and add tests that simulate switching users within the same client.
Affected Versions
Django 0.95 (pre-patch)
Code Fix Example
Django API Security Remediation
Vulnerable pattern:
import threading
# Global cache across requests (unsafe)
_cached_username = None
def get_username_vuln(request):
global _cached_username
if _cached_username is None:
_cached_username = getattr(request.user, 'username', None)
return _cached_username
def access_sensitive_resource_vuln(request):
if get_username_vuln(request) == 'admin':
grant_access()
def grant_access():
print('Access granted')
# Fixed pattern:
def get_username_fix(request):
# Do not cache: per-request
return getattr(request.user, 'username', None)
def access_sensitive_resource_fix(request):
if get_username_fix(request) == 'admin':
grant_access()