Fix Lack of Resources & Rate Limiting in Django
Unrestricted endpoints are a goldmine for DoS attacks and credential stuffing. Without resource capping and rate limiting, an attacker can exhaust your server's RAM, CPU, and DB connections with minimal effort. To harden Django, you must enforce request ceilings and payload size limits.
The Vulnerable Pattern
from django.http import JsonResponsedef login_view(request): # VULNERABLE: No rate limiting. Attacker can brute-force indefinitely. # No check on request body size; huge payloads can trigger OOM (Out of Memory). data = request.POST.get(‘password’) return JsonResponse({‘status’: ‘attempted’})
def search_view(request): # VULNERABLE: Expensive DB query without pagination or limits. results = MyModel.objects.filter(name__icontains=request.GET.get(‘q’)) return JsonResponse({‘data’: list(results.values())})
The Secure Implementation
The fix targets three vectors: 1. Network/Request Level: Using `django-ratelimit` to block IPs exceeding a defined threshold, preventing brute-force. 2. Memory Level: Configuring `DATA_UPLOAD_MAX_MEMORY_SIZE` in settings.py prevents attackers from sending massive multi-gigabit payloads that crash the worker process. 3. Database Level: Enforcing pagination using Django's `Paginator` ensures that a single query cannot fetch millions of rows, which would otherwise cause DB contention and high memory usage.
# settings.py DATA_UPLOAD_MAX_MEMORY_SIZE = 2621440 # Limit to 2.5MB DATA_UPLOAD_MAX_NUMBER_FIELDS = 1000views.py
from django_ratelimit.decorators import ratelimit from django.core.paginator import Paginator
@ratelimit(key=‘ip’, rate=‘5/m’, method=‘POST’, block=True) def secure_login_view(request): # SECURE: Throttled to 5 attempts per minute per IP. return JsonResponse({‘status’: ‘secure_attempt’})
def secure_search_view(request): # SECURE: Pagination prevents massive memory consumption from DB results. query = request.GET.get(‘q’, ”) objects = MyModel.objects.filter(name__icontains=query).order_by(‘id’) paginator = Paginator(objects, 20) # Max 20 results per page page_number = request.GET.get(‘page’) page_obj = paginator.get_page(page_number) return JsonResponse({‘data’: [i.name for i in page_obj]})
Your Django API
might be exposed to Lack of Resources & Rate Limiting
74% of Django apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.