Scope: Security standards and hardening guidance for Django applications. Focuses on built-in security features, production settings, ORM safety, object-level authorization, CSRF defense, and file upload boundaries.
TorusGuard identifies Django projects by detecting manage.py, wsgi.py, asgi.py, settings.py, or django in dependency manifests.
Django includes robust production security mechanisms that must be explicitly configured for non-development environments.
# settings.py - Production Configuration
import os
from pathlib import Path
# 1. Disable Debug Mode in Production (TG-PLATFORM-003)
DEBUG = False
# 2. Secret Key from Environment (TG-SEC-001)
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY")
if not SECRET_KEY and not DEBUG:
raise RuntimeError("DJANGO_SECRET_KEY must be set in production.")
# 3. Explicit Allowed Hosts (TG-PLATFORM-001)
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "example.com,api.example.com").split(",")
# 4. HTTPS and Cookie Security Flags
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
CSRF_COOKIE_SAMESITE = "Lax"
# 5. HTTP Strict Transport Security (HSTS)
SECURE_HSTS_SECONDS = 31536000 # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
# 6. Content Security & XSS Headers
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = "DENY"Verification Command:
python manage.py check --deploy(Note: manage.py check --deploy is a helpful baseline check, but does not substitute for full configuration review.)
Django includes built-in CSRF protection enabled by default via django.middleware.csrf.CsrfViewMiddleware.
- Ensure
'django.middleware.csrf.CsrfViewMiddleware'is present inMIDDLEWARE. - In all template POST forms, include
{% csrf_token %}. - For AJAX requests, read the CSRF cookie or send the
X-CSRFTokenheader. - Avoid using
@csrf_exempton session-authenticated routes. If building an unauthenticated external webhook handler, verify signatures manually rather than relying solely on@csrf_exempt.
Django's ORM automatically parameterizes SQL queries. However, raw SQL methods require caution.
# VULNERABLE: Direct string interpolation into raw SQL
email = request.POST.get("email")
users = User.objects.raw(f"SELECT * FROM auth_user WHERE email = '{email}'")# SAFE: Use ORM queryset lookups
email = request.POST.get("email")
users = User.objects.filter(email=email)
# SAFE: If raw SQL is strictly required, use parameters list/dict
users = User.objects.raw("SELECT * FROM auth_user WHERE email = %s", [email])A numeric primary key in a URL must never be queried without filtering by the authenticated user.
# VULNERABLE: Any logged-in user can view document #42 by guessing the ID
@login_required
def view_document(request, doc_id):
doc = get_object_or_404(Document, id=doc_id)
return render(request, "doc.html", {"doc": doc})# SAFE: Scope lookup strictly to the authenticated user's records
@login_required
def view_document(request, doc_id):
doc = get_object_or_404(Document, id=doc_id, owner=request.user)
return render(request, "doc.html", {"doc": doc})ModelForm classes must explicitly define allowed editable fields.
# VULNERABLE: Allows client to submit 'is_staff' or 'is_superuser'
class UserProfileForm(forms.ModelForm):
class Meta:
model = User
fields = '__all__' # ❌ Dangerous mass assignment# SAFE: Explicit whitelist of safe fields
class UserProfileForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'last_name', 'email', 'bio'] # ✅ Safe whitelist- Storage: Store user uploads in dedicated object storage (AWS S3, Google Cloud Storage) or outside the web server's executable document root.
- File Validation: Validate allowed extensions, file size, and MIME content.
- Execution Prevention: Ensure the web server (Nginx/Apache) does not execute PHP/Python/CGI scripts in the
MEDIA_ROOTdirectory.
Use @never_cache on sensitive user views (billing, profile, reset password) to prevent caching in public intermediate proxies.
from django.views.decorators.cache import never_cache
@never_cache
@login_required
def billing_details(request):
return render(request, "billing.html", {"billing": request.user.billing_profile})-
DEBUGis set toFalsein production environments. -
SECRET_KEYis loaded from a secure environment variable and never committed. -
ALLOWED_HOSTScontains only explicit domain names (no wildcard*with credentials). -
CsrfViewMiddlewareis enabled inMIDDLEWARE. - All
ModelFormdefinitions use explicitfieldsarrays rather than'__all__'. - All object lookups by numeric ID filter by
request.useror tenant ID. - The Django Admin path is hardened or restricted via IP allowlist / 2FA.
- File uploads validate extension, size, and use dedicated storage.