| name | django-security |
| description | Applies Django security patterns for auth, CSRF, XSS, and deployment. Use when this capability is needed. |
| metadata | {"author":"basidiocarp"} |
Django Security Best Practices
Contents
Comprehensive security guidelines for Django applications to protect against common vulnerabilities.
When to Use
- Setting up Django authentication and authorization
- Implementing user permissions and roles
- Configuring production security settings
- Reviewing Django application for security issues
- Deploying Django applications to production
Installation
pip install django
Quick Security Checklist
| Check | Description |
|---|
DEBUG = False | Never run with DEBUG in production |
| HTTPS only | Force SSL, secure cookies |
| Strong secrets | Use environment variables for SECRET_KEY |
| Password validation | Enable all password validators |
| CSRF protection | Enabled by default, don't disable |
| XSS prevention | Django auto-escapes, don't use ` |
| SQL injection | Use ORM, never concatenate strings in queries |
| File uploads | Validate file type and size |
| Rate limiting | Throttle API endpoints |
| Security headers | CSP, X-Frame-Options, HSTS |
Core Security Settings
DEBUG = False
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
ALLOWED_HOSTS = ["example.com"]
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
if not SECRET_KEY:
raise ImproperlyConfigured('DJANGO_SECRET_KEY required')
Authentication Quick Reference
class User(AbstractUser):
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
AUTH_USER_MODEL = 'users.User'
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.Argon2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
]
Authorization Quick Reference
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
class PostUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
model = Post
permission_required = 'app.can_edit_others'
raise_exception = True
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.author == request.user
Injection Prevention
SQL Injection
User.objects.filter(username=user_input)
User.objects.raw('SELECT * FROM users WHERE username = %s', [user_input])
User.objects.raw(f'SELECT * FROM users WHERE username = {user_input}')
XSS Prevention
{# Django auto-escapes by default - SAFE #}
{{ user_input }}
{# Only use |safe for trusted content #}
{{ trusted_html|safe }}
{# JavaScript escaping #}
<script>var name = {{ username|escapejs }};</script>
CSRF Protection
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
Reference Files
| File | Description |
|---|
| production-settings.md | Full production config, env vars, logging |
| authentication.md | Custom user model, password hashing, sessions |
| authorization.md | Permissions, RBAC, DRF permissions |
| injection-prevention.md | SQL injection, XSS, CSRF full examples |
| api-security.md | Rate limiting, API auth, CSP, file uploads |
Remember: Security is a process, not a product. Regularly review and update your security practices.
Source: basidiocarp/lamella — distributed by TomeVault.