Django

⌘K
  1. Home
  2. Django
  3. Security setup

Security setup

Securing your Django project is crucial, especially when deploying to production. Below is a step-by-step guide to enable the best security settings for your project.


Step 1: Set DEBUG = False for Production

By default, Django runs in debug mode (DEBUG = True), which shows sensitive error messages.
For production, always disable it.

📌 Update settings.py

DEBUG = False  # Disable debug mode in production

Why?

  • Prevents sensitive error messages from being displayed publicly.
  • Hides internal details of your app.

Step 2: Set ALLOWED_HOSTS

Django requires you to define allowed domains to prevent HTTP Host header attacks.

📌 Update settings.py

ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']

Why?

  • Blocks attackers from sending requests using fake hostnames.
  • Prevents security vulnerabilities like Host Header Injection.

Step 3: Use SECRET_KEY from .env

Never hardcode your SECRET_KEY in settings.py. Instead, store it securely in a .env file.

📌 Install python-decouple

pip install python-decouple

📌 Create .env in the project root

SECRET_KEY=your-very-secure-secret-key

📌 Update settings.py

from decouple import config

SECRET_KEY = config('SECRET_KEY')

Why?

  • Protects your secret key from exposure in GitHub or public repositories.

Step 4: Enable Security Middleware

Django provides built-in middleware to protect against various attacks.

📌 Update settings.py

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',  # Security features
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',  # Protects against CSRF attacks
    'django.middleware.clickjacking.XFrameOptionsMiddleware',  # Prevents clickjacking
    'whitenoise.middleware.WhiteNoiseMiddleware',  # Serves static files securely
]

Why?

  • Protects against clickjacking, CSRF, and session hijacking.

Step 5: Enforce HTTPS

For production, always use HTTPS by enabling secure cookies and HSTS.

📌 Update settings.py

SECURE_SSL_REDIRECT = True  # Redirect all HTTP requests to HTTPS
SESSION_COOKIE_SECURE = True  # Prevent session hijacking
CSRF_COOKIE_SECURE = True  # Secure CSRF cookie
SECURE_BROWSER_XSS_FILTER = True  # Enable XSS protection
SECURE_CONTENT_TYPE_NOSNIFF = True  # Prevent MIME-type sniffing
X_FRAME_OPTIONS = 'DENY'  # Prevent clickjacking
SECURE_HSTS_SECONDS = 31536000  # Enable HTTP Strict Transport Security (1 year)
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True

Why?

  • Prevents man-in-the-middle (MITM) attacks.
  • Forces all requests to use HTTPS.
  • Stops malicious scripts from running on your site.

Step 6: Configure CSRF_TRUSTED_ORIGINS

If you’re hosting your app on a domain, you must explicitly allow it for CSRF protection.

📌 Update settings.py

CSRF_TRUSTED_ORIGINS = ['https://yourdomain.com', 'https://www.yourdomain.com']

Why?

  • Prevents CSRF attacks where attackers try to submit forms on behalf of users.

Step 7: Use a Strong Database Password

If using PostgreSQL or MySQL, never use weak passwords.

📌 Update settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'yourdbname',
        'USER': 'yourdbuser',
        'PASSWORD': config('DB_PASSWORD'),  # Load from .env
        'HOST': 'your-db-host',
        'PORT': '5432',  # Default PostgreSQL port
    }
}

Why?

  • Prevents database access from unauthorized users.
  • Keeps credentials secret by using .env.

Step 8: Use django-environ for Extra Security

Instead of hardcoding sensitive settings, use django-environ.

📌 Install django-environ

pip install django-environ

📌 Update settings.py

import environ

env = environ.Env()
environ.Env.read_env()

SECRET_KEY = env('SECRET_KEY')
DEBUG = env.bool('DEBUG', default=False)
DATABASES = {
    'default': env.db()
}

📌 Create .env

DEBUG=False
SECRET_KEY=your-secret-key
DATABASE_URL=postgres://yourdbuser:yourdbpassword@your-db-host/yourdbname

Why?

  • Enhances security by keeping credentials outside of code.

Step 9: Disable Django Admin in Production

To hide Django Admin from attackers, do the following:

📌 Update urls.py

from django.conf import settings
from django.contrib import admin
from django.urls import path

urlpatterns = []

if settings.DEBUG:
    urlpatterns += [path('admin/', admin.site.urls)]

Why?

  • Prevents admin panel access from public users.

Step 10: Use gunicorn for Deployment

For production, use Gunicorn instead of Django’s built-in server.

📌 Install Gunicorn

pip install gunicorn

📌 Run Gunicorn

gunicorn --bind 0.0.0.0:8000 config.wsgi:application

Why?

  • Gunicorn is optimized for production.
  • Handles multiple requests better than the default server.

Step 11: Use a Procfile for cPanel Deployment

If deploying to cPanel or Heroku, add a Procfile.

📌 Create Procfile in the project root

web: gunicorn config.wsgi --log-file -

Why?

  • Required for Heroku or cPanel Passenger deployment.

Final Security Checklist

DEBUG = False
Set ALLOWED_HOSTS
Keep SECRET_KEY in .env
Enable HTTPS with SECURE_SSL_REDIRECT
Use strong database passwords
Use Gunicorn for deployment
Hide Django Admin in production
Use CSRF & Clickjacking protection


🎯 Now Your Django Project is Secure & Production Ready!

🚀 Let me know if you need further clarification. 😊

Articles

How can we help?