Overview
SSRF in Django guide (note CVE-2007-5712). This guide references a real-world vulnerability in Django's i18n framework, where enabling USE_I18N and the i18n components allowed attackers to exhaust memory via many requests with oversized Accept-Language headers, leading to denial of service. CVE-2007-5712 documents this issue in Django 0.91, 0.95, 0.95.1, and 0.96, and notes that it could be triggered by the way locale processing interacted with translation loading. The patch reduces the risk by changing or tightening how language negotiation is handled, and by removing or constraining the i18n processing path in deployments where it is unnecessary. This class of vulnerability demonstrates how overly permissive parsing of client-provided headers in Django canResult in resource exhaustion under load, underscoring the need for careful configuration and limits around internationalization features.
Affected Versions
Django 0.91, 0.95, 0.95.1, 0.96
Code Fix Example
Django API Security Remediation
Vulnerable pattern (Django <= 0.96 with i18n enabled):
# settings.py
USE_I18N = True
MIDDLEWARE = [
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
# ...
]
# views.py
from django.http import HttpResponse
from django.utils import translation
def index(request):
# Accept-Language header may be very large and trigger heavy locale processing
lang = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
translation.activate(lang)
return HttpResponse("Hello")
# Fixed pattern (safe defenses):
# settings.py
USE_I18N = False # or remove LocaleMiddleware if i18n is not required
MIDDLEWARE = [
'django.middleware.common.CommonMiddleware',
# LocaleMiddleware removed or replaced with a guarded approach
]
# Or keep i18n but guard/limit header before it reaches LocaleMiddleware
# middleware.py
class LimitAcceptLanguageMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
header = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
if len(header) > 1024:
request.META['HTTP_ACCEPT_LANGUAGE'] = header[:1024]
return self.get_response(request)
# then insert this middleware high in the stack
MIDDLEWARE.insert(0, 'path.to.LimitAcceptLanguageMiddleware')