Django Security Checklist: 10 Steps to Bulletproof Your DjangoWeb App
I have been working with Django for the past five years, and my journey with it continues. Django is one of the most secure web frameworks…

I have been working with Django for the past five years, and my journey with it continues. Django is one of the most secure web frameworks available. In this guide, we will dive deep into a 10-step security checklist that will help you strengthen your Django application against potential attacks.
1. Keep Your Django Version Up to Date
Django regularly releases security patches — ensure you’re always on the latest LTS (Long-Term Support) version.
Check your version:
python -m django --version
You can follow the official docs to get the latest version https://www.djangoproject.com/download/
2. Set DEBUG = False
in Production
If you are leaving DEBUG = True
in your settings file it can exposes sensitive error messages.
Update settings.py
:
# settings.py
DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com']
3. Secure Your Secret Key
The SECRET_KEY
is critical for cryptographic signing—never hardcode it in your settings file.
Use environment variables or a .env
file:
DJANGO_SECRET_KEY='your-secure-key'
Use django-environ to manage secrets easily:
pip install django-environ
# settings.py
import environ
import os
env = environ.Env()
SECRET_KEY = env('SECRET_KEY')
4. Use a Strong Password Hasher
The Default password hashing is PBKDF2, but Argon2 is more secure.
Update settings.py
:
# settings.py
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.Argon2PasswordHasher',
]
5. Enable HTTPS with SECURE_*
Settings
Always serve your app over HTTPS to prevent MITM attacks.
Update settings.py
:
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
6. Protect Against Clickjacking & XSS Attacks
Use CSP headers and frame protection.
Update settings.py
:
X_FRAME_OPTIONS = 'DENY'
SECURE_BROWSER_XSS_FILTER = True
CSP_DEFAULT_SRC = ("'self'",)
You can use django-csp for fine-grained CSP policies.
pip install django-csp
# settings.py
from csp.constants import NONE, SELF
INSTALLED_APPS = [
"csp"
]
MIDDLEWARE = (
"csp.middleware.CSPMiddleware",
)
# The CONTENT_SECURITY_POLICY setting is your enforceable policy.
CONTENT_SECURITY_POLICY = {
"EXCLUDE_URL_PREFIXES": ["/excluded-path/"],
"DIRECTIVES": {
"default-src": [SELF, "cdn.example.net"],
"frame-ancestors": [SELF],
"form-action": [SELF],
"report-uri": "/csp-report/",
},
}
# The CONTENT_SECURITY_POLICY_REPORT_ONLY setting is your report-only policy.
# This policy is used to test the policy without breaking the site.
# It is useful when setting this policy to be slightly more strict than
# the default policy to see what would be blocked if the policy was enforced.
CONTENT_SECURITY_POLICY_REPORT_ONLY = {
"EXCLUDE_URL_PREFIXES": ["/excluded-path/"],
"DIRECTIVES": {
"default-src": [NONE],
"connect-src": [SELF],
"img-src": [SELF],
"form-action": [SELF],
"frame-ancestors": [SELF],
"script-src": [SELF],
"style-src": [SELF],
"upgrade-insecure-requests": True,
"report-uri": "/csp-report/",
},
}
7. Prevent SQL Injection
Never concatenate raw SQL queries — always use Django ORM.
Safe query:
User.objects.filter(email=email).first()
Unsafe (Don’t do this!):
cursor.execute(f"SELECT * FROM users WHERE email = '{email}'") # ❌ SQL Injection risk
8. Restrict File Uploads
Prevent malicious file uploads.
Update settings.py
:
FILE_UPLOAD_PERMISSIONS = 0o640
Use django-storages for cloud-based storage.
9. Use Django’s Built-in Security Middleware
Django provides middleware for various security measures — ensure they are enabled.
Check settings.py
:
# settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
10. Enable Logging & Monitoring
Monitor your app for suspicious activity and security breaches.
Configure logging in settings.py
:
# settings.py
LOGGING = {
'version': 1,
'handlers': {
'file': {
'level': 'ERROR',
'class': 'logging.FileHandler',
'filename': 'django_errors.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'ERROR',
'propagate': True,
},
},
}
You can use Sentry for real-time error tracking.
Final Thoughts
Implementing these 10 security best practices will protect your Django app against common attacks and make your Django app bulletproof.
Next Steps:
Run Django’s security check before deployment:
python manage.py check --deploy
Use penetration testing tools like ZAP
Which security step do you always follow? Drop a comment below! 🚀