Denial Of Service in Django with Basic Auth
Denial Of Service in Django with Basic Auth — how this specific combination creates or exposes the vulnerability
When Basic Authentication is used in Django without additional protections, the combination of predictable authentication flow and lack of request-rate constraints can amplify Denial of Service (DoS) risks. Basic Auth transmits credentials in an encoded (not encrypted) format and requires the server to validate credentials on many requests. If an endpoint is unauthenticated in design but still parses and rejects Basic Auth headers, Django may still perform work to decode and inspect those headers. Inefficient authentication logic or unnecessary database queries triggered by auth checks can increase per-request resource usage.
In a black-box scan, middleBrick tests unauthenticated attack surfaces and includes Authentication and Rate Limiting checks. These checks can surface scenarios where endpoints accept repeated authentication attempts or malformed headers that cause excessive CPU or memory consumption. For example, an endpoint that processes large or numerous Authorization headers without length or rate limits may become vulnerable to header-spray or slowloris-style attacks that keep connections open or exhaust thread/worker capacity. Even without credentials, malformed or many concurrent requests with Basic Auth headers can trigger repeated decoding and validation logic, contributing to service degradation.
Furthermore, if Basic Auth validation is implemented in middleware or custom decorators that perform additional database lookups or file I/O on every request, an attacker can force expensive operations by sending many authenticated-looking requests. This is especially relevant when the scanning categories Authentication and Rate Limiting are both exercised: the scanner verifies whether authentication checks are lightweight and whether rate limiting exists to curb abusive request patterns. The interplay between Basic Auth enforcement and missing rate controls can result in high CPU or connection exhaustion, effectively creating a DoS vector.
Basic Auth-Specific Remediation in Django — concrete code fixes
To reduce DoS exposure when using HTTP Basic Authentication in Django, implement rate limiting, validate and restrict headers early, and avoid expensive work for malformed or non-essential auth requests. The following examples show a secure approach using Django middleware and view-level protections.
1. Lightweight Basic Auth validation with early header checks
Reject obviously malformed or oversized Authorization headers before performing expensive decoding or database operations.
import base64
import re
from django.http import HttpResponseBadRequest, HttpResponse
from django.utils.deprecation import MiddlewareMixin
class BasicAuthDoSMiddleware(MiddlewareMixin):
# Reject suspiciously long or malformed Authorization headers early
def process_request(self, request):
auth = request.META.get('HTTP_AUTHORIZATION', '')
if auth.startswith('Basic '):
token = auth.split(' ', 1)[1].strip()
# Basic64 length guard: header should not exceed reasonable size
if len(token) > 128:
return HttpResponseBadRequest('Authorization header too long')
# Only allow base64 chars and optional padding
if not re.fullmatch(r'[A-Za-z0-9+/=]+', token):
return HttpResponseBadRequest('Malformed Authorization header')
# Optionally defer actual credential validation to view if needed
return None
def my_protected_view(request):
auth = request.META.get('HTTP_AUTHORIZATION', '')
if not auth.startswith('Basic '):
return HttpResponse(status=401, headers={'WWW-Authenticate': 'Basic realm="api"'})
try:
decoded = base64.b64decode(auth.split(' ', 1)[1]).decode('utf-8')
except Exception:
return HttpResponseBadRequest('Invalid credentials encoding')
username, _, password = decoded.partition(':')
# Perform lightweight credential check (e.g., via cache or hashed lookup)
if not (username == 'admin' and password == 's3cret'):
return HttpResponse(status=403)
return HttpResponse('OK')
2. Rate limiting with Django Ratelimit
Apply per-IP or per-username rate limits to authentication endpoints to prevent credential spraying or connection exhaustion.
from ratelimit.decorators import ratelimit
from django.http import HttpResponse
@ratelimit(key='ip', rate='10/m', block=True)
@ratelimit(key='user', rate='5/m', block=True)
def login_with_basic(request):
auth = request.META.get('HTTP_AUTHORIZATION', '')
if auth.startswith('Basic '):
# validate credentials as needed
return HttpResponse('Authenticated')
return HttpResponse(status=401, headers={'WWW-Authenticate': 'Basic realm="api"'})
3. Middleware-based global rate and header controls
Use middleware to enforce global request caps and drop abusive connections before they reach views.
from django.http import HttpResponseForbidden
class RateAndHeaderMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.request_counts = {}
def __call__(self, request):
ip = request.META.get('REMOTE_ADDR')
self.request_counts[ip] = self.request_counts.get(ip, 0) + 1
if self.request_counts[ip] > 100:
return HttpResponseForbidden('Rate limit exceeded')
response = self.get_response(request)
return response
4. Using Django settings to disable Basic Auth when not required
If an endpoint does not need authentication, ensure middleware that parses Authorization headers is not applied, or use conditional checks to avoid unnecessary processing.
# settings.py
USE_BASIC_AUTH = False # Toggle per environment
# middleware.py
from django.conf import settings
class ConditionalBasicAuthMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if settings.USE_BASIC_AUTH:
# perform lightweight validation
pass
return self.get_response(request)
These measures align with the middleBrick categories Authentication and Rate Limiting by ensuring that Basic Auth validation is efficient, headers are validated early, and abusive request patterns are curtailed. They complement continuous monitoring capabilities offered by plans such as the Pro plan, which includes GitHub Action integration for CI/CD pipeline gates and alerts.
Related CWEs: resourceConsumption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-400 | Uncontrolled Resource Consumption | HIGH |
| CWE-770 | Allocation of Resources Without Limits | MEDIUM |
| CWE-799 | Improper Control of Interaction Frequency | MEDIUM |
| CWE-835 | Infinite Loop | HIGH |
| CWE-1050 | Excessive Platform Resource Consumption | MEDIUM |