A comprehensive security checklist for Django developers before uploading or deploying projects
- Why This Checklist?
- Quick Scan
- Detailed Checklist
- Pre-Upload Tools
- Emergency Procedures
- Safe settings.py Template
- Manual Upload Security Guide
- Contributing
- License
Accidentally committing secrets or misconfiguring Django settings is one of the most common security pitfalls. This checklist helps you avoid:
- API key exposure
- Database credential leaks
- Debug mode in production
- Insecure settings configuration
- Accidental secret commits
Run these commands immediately before any commit:
# Scan for secrets
grep -r "SECRET_KEY" . --include="*.py"
grep -r "password" . --include="*.py" -i
grep -r "API_KEY" . --include="*.py" -i
# Check critical settings
grep -n "DEBUG" settings.py
grep -n "ALLOWED_HOSTS" settings.py
# Find sensitive files
find . -name "*.sqlite3" -o -name ".env" -o -name "*.pyc"- SECRET_KEY removed from settings.py
- Database files (.sqlite3, .db) removed
- Environment files (.env, .yml) deleted
- DEBUG set to False
- ALLOWED_HOSTS properly configured (not
['*']) - API keys, tokens, and passwords removed from code
-
db.sqlite3and any*.dbfiles -
.envand environment configuration files -
*.pyccompiled Python files -
__pycache__/directories - IDE-specific files (
.vscode/,.idea/) - Log files (
*.log)
-
DEBUG = Falsefor production -
ALLOWED_HOSTS = ['yourdomain.com'](specific hosts, not['*']) -
CSRF_COOKIE_SECURE = True -
SESSION_COOKIE_SECURE = True -
SECURE_BROWSER_XSS_FILTER = True -
SECURE_CONTENT_TYPE_NOSNIFF = True -
X_FRAME_OPTIONS = 'DENY'
pip install bandit safety# Scan Python code for security issues
bandit -r .
# Check for vulnerable packages
safety check
# Generate HTML report
bandit -r . -f html -o security_report.html
# Check for secrets
git secrets --scan # If using git-secrets# 1. ROTATE KEYS IMMEDIATELY (API keys, database passwords, etc.)
# 2. Rewrite git history
git filter-repo --force --invert-paths --path sensitive-file.txt
# 3. Force push
git push origin --force --all
# 4. Verify the secrets are gone
git log --oneline # Check history# settings.py (Safe Template - Use Environment Variables)
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# Environment variables for security - NEVER HARDCODE THESE!
SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-key-only-for-development')
DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true'
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(',')
# Database configuration via environment variables
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
# For production, use environment variables:
# 'NAME': os.environ.get('DB_NAME'),
# 'USER': os.environ.get('DB_USER'),
# 'PASSWORD': os.environ.get('DB_PASSWORD'),
# 'HOST': os.environ.get('DB_HOST'),
# 'PORT': os.environ.get('DB_PORT'),
}
}
# Security headers (auto-enable in production)
if not DEBUG:
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000 # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = TrueWhen manually uploading Django projects, these are the most critical security concerns:
NEVER COMMIT THESE:
# Django Secret Key (in settings.py)
SECRET_KEY = 'your-super-secret-key-here' # β REMOVE BEFORE UPLOAD
# Database passwords
DATABASES = {
'default': {
'PASSWORD': 'your-database-password', # β REMOVE
}
}
# API keys, tokens, and secrets
API_KEY = 'sk_live_1234567890' # β REMOVE
AWS_ACCESS_KEY = 'AKIA...' # β REMOVE
STRIPE_SECRET_KEY = 'sk_test_...' # β REMOVESolution: Always use environment variables:
# settings.py - SAFE APPROACH
import os
SECRET_KEY = os.environ.get('SECRET_KEY', 'fallback-for-dev-only')
DATABASE_PASSWORD = os.environ.get('DB_PASSWORD')
API_KEY = os.environ.get('API_KEY')Remove immediately:
db.sqlite3(contains user data, emails, progress, potentially sensitive information)- Any
.dbfiles - Database backups (
*.backup,*.bak)
Delete before upload:
.envfiles (often contain secrets)environment.yml/.env.example(might contain template secrets)- Any file containing credentials or configuration secrets
Ensure this is FALSE:
# settings.py
DEBUG = False # β Must be False for production/public codeSet properly (never use wildcard):
# settings.py - UNSAFE
ALLOWED_HOSTS = ['*'] # β Dangerous! Allows any host
# settings.py - SAFE
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com'] # β Specific hosts only# Search for secrets in your code
grep -r "SECRET_KEY" . --include="*.py"
grep -r "password" . --include="*.py" -i
grep -r "API_KEY" . --include="*.py" -i
grep -r "token" . --include="*.py" -i
grep -r "key" . --include="*.py" -i | grep -v "foreign" | grep -v "primary"
# Check for debug mode and settings
grep -n "DEBUG" settings.py
grep -n "ALLOWED_HOSTS" settings.py
grep -A 10 -B 5 "DATABASES" settings.py
# Find sensitive files
find . -name "*.sqlite3" -o -name "*.db" -o -name ".env" -o -name "*.pyc"settings.py- Most critical file (contains most secrets).env/.env.example- Environment files*.jsonconfig files - Might contain API keysrequirements.txt- Check for vulnerable packagesdocker-compose.yml- Might contain hardcoded credentials
# Install security scanners
pip install bandit safety
# Scan for Python vulnerabilities and security issues
bandit -r .
# Check for vulnerable packages in requirements.txt
safety check
# Alternative: use git-secrets for pattern matching
git secrets --install
git secrets --register-aws
git secrets --scan
# Create a safe archive without sensitive files
zip -r project-safe.zip . -x "*.sqlite3" "venv/*" ".env" "__pycache__/*" "*.pyc" ".git/*"- Remove
SECRET_KEYfrom settings.py - Delete
db.sqlite3and any database files - Remove any
.envfiles and environment configurations - Set
DEBUG = False - Configure
ALLOWED_HOSTSproperly (not['*']) - Check for hardcoded API keys and passwords
- Remove any personal data, emails, or sensitive comments
- Scan with
banditandsafety check - Update packages in
requirements.txtto latest secure versions - Remove unused imports and dead code
- Check file permissions (no world-writable files)
- Review error messages for information leakage
- Validate all form inputs and use Django's security features
If you accidentally commit secrets, act immediately:
-
ROTATE ALL EXPOSED KEYS - This is the most critical step!
- Change database passwords
- Rotate API keys
- Generate new secret keys
- Revoke and replace any exposed tokens
-
Rewrite git history to remove the secrets:
# Install git-filter-repo if needed
pip install git-filter-repo
# Remove sensitive files from history
git filter-repo --force --invert-paths --path secrets.txt
git filter-repo --force --invert-paths --path settings.py # If it contained secrets- Force push to all branches:
git push origin --force --all
git push origin --force --tags- Verify the cleanup:
git log --oneline # Check that sensitive commits are gone
git grep "secret_key" # Search for any remaining secrets- Monitor for abuse - Watch for unauthorized access attempts on your services
Even if just uploading to GitHub, assume someone might try to deploy your code:
- Use environment variables for all secrets and configurations
- Add clear deployment instructions in README.md
- Include security settings in your code
- Mention required environment variables
- Provide example environment files (without real secrets)
Before uploading, run this comprehensive check:
#!/bin/bash
echo "π Final Security Check"
echo "======================"
# Check for secrets
echo "1. Searching for secrets..."
grep -r "SECRET_KEY" . --include="*.py" | grep -v "os.environ.get" && echo "β Hardcoded secrets found!"
# Check settings
echo "2. Checking settings..."
grep -n "DEBUG" settings.py | grep "True" && echo "β DEBUG is True!"
grep -n "ALLOWED_HOSTS" settings.py | grep "\*" && echo "β ALLOWED_HOSTS contains wildcard!"
# Check for sensitive files
echo "3. Checking for sensitive files..."
find . -name "*.sqlite3" -o -name ".env" | xargs -I {} echo "β Found: {}"
echo "======================"
echo "β
Final check completed. Review any warnings above."Found a new security concern? Please contribute!
- Fork the repository
- Add your security tip or improvement
- Submit a pull request
- Help keep the Django community secure!
MIT License - feel free to use this checklist for your projects! See LICENSE file for details.
- Django Security Documentation
- OWASP Django Security Cheat Sheet
- GitHub Secret Scanning
- Bandit - Python Security Scanner
- Safety - Dependency Check
- Automate scans with git pre-commit hooks
- Use CI/CD to run security checks automatically
- Regularly update your dependencies
- Educate your team on security best practices
- Assume breach - plan what you'll do if secrets are exposed
By following this comprehensive checklist, you'll ensure your Django projects are secure before they ever leave your development environment! π‘οΈ
Remember: Security is a process, not a product. Regular reviews and vigilance are key to maintaining secure applications.