Django
34 items · source
Backend Application & API
- Verify
DEBUG = Falsein production, and that no code path re-enables it. - Verify
ALLOWED_HOSTSis an explicit list, never['*']. - Verify
SECURE_SSL_REDIRECT,SESSION_COOKIE_SECURE,CSRF_COOKIE_SECUREandSECURE_HSTS_SECONDSare set. - Verify
SECURE_PROXY_SSL_HEADERmatches your actual proxy, or is absent — a wrong value lets a client claim HTTPS. - Run
python manage.py check --deployand resolve every warning or record why it is accepted. - Audit every
@csrf_exempt; confirm the endpoint authenticates by a mechanism CSRF cannot forge. - Verify the Django admin is not reachable at the default path in production, and is behind authentication plus network controls.
- Verify
X_FRAME_OPTIONSisDENYunless framing is required.
Authentication & Authorization
- Verify DRF
DEFAULT_PERMISSION_CLASSESis restrictive; a missing default meansAllowAny. - Audit every view that sets
permission_classes = [AllowAny]. - Verify
get_querysetfilters by the requesting user or tenant, rather than filtering in the serializer or template. - Verify
ModelSerializerwithfields = '__all__'does not expose internal or ownership fields. - Verify serializer
read_only_fieldscovers every field a client must not set, includinguser,ownerandis_staff. - Verify
@login_required/LoginRequiredMixinis present on every non-public view, including class-based ones.
Database & Row-Level Security
- Search for
.raw(,.extra(,connection.cursor()and any f-string or%formatting inside a query. - Verify
filter(**request.GET.dict())or equivalent mass-filtering is not exposed — it lets a caller query relations you did not intend. - Verify
order_by(request.GET['sort'])is allowlisted.
Web Frontend
- Search templates for
|safe,{% autoescape off %}, andmark_safein Python. - Verify
json_scriptis used for passing data to JavaScript rather than raw interpolation.
Sessions, Tokens & Cookies
- Verify
SESSION_SERIALIZERis the JSON serializer; the pickle serializer turns session tampering into code execution. - Verify
SECRET_KEYcomes from the environment and differs per environment. - Verify
SESSION_COOKIE_SAMESITEandCSRF_COOKIE_SAMESITEare set.
Object Storage & File Handling
- Verify uploaded files are validated by content, not by extension or the client-supplied content type.
- Verify
MEDIA_ROOTis not served by the application in production, and that user uploads cannot be executed. - Verify
FileField/ImageFieldupload paths cannot be influenced by user input.
Pre-Release Gates
- Verify
django-debug-toolbaranddjango-extensionsare not installed in production. - Verify
pip-auditorsafetyruns in CI and no known-vulnerable package ships.
Backend & Delivery
- Verify
select_relatedandprefetch_relatedare used on the querysets that render each page; the ORM makes N+1 effortless. - Verify
django-debug-toolbarornplusonehas been run against the real templates in development to count queries per page. - Verify
CONN_MAX_AGEis set so a connection is not opened per request, and is compatible with your pooling setup. - Verify template fragment caching or the cache framework is used for expensive rendered sections.
- Verify
.only()and.defer()are used where a view loads large columns it does not display. - Verify
QuerySet.count()is not called on large tables in a hot path whenexists()would do.
Measurement
- Verify
django-silkor equivalent has profiled the slowest views against production-like data volumes, not a seeded fixture.
# Django
## Backend Application & API
* [ ] Verify `DEBUG = False` in production, and that no code path re-enables it.
* [ ] Verify `ALLOWED_HOSTS` is an explicit list, never `['*']`.
* [ ] Verify `SECURE_SSL_REDIRECT`, `SESSION_COOKIE_SECURE`, `CSRF_COOKIE_SECURE` and `SECURE_HSTS_SECONDS` are set.
* [ ] Verify `SECURE_PROXY_SSL_HEADER` matches your actual proxy, or is absent — a wrong value lets a client claim HTTPS.
* [ ] Run `python manage.py check --deploy` and resolve every warning or record why it is accepted.
* [ ] Audit every `@csrf_exempt`; confirm the endpoint authenticates by a mechanism CSRF cannot forge.
* [ ] Verify the Django admin is not reachable at the default path in production, and is behind authentication plus network controls.
* [ ] Verify `X_FRAME_OPTIONS` is `DENY` unless framing is required.
## Authentication & Authorization
* [ ] Verify DRF `DEFAULT_PERMISSION_CLASSES` is restrictive; a missing default means `AllowAny`.
* [ ] Audit every view that sets `permission_classes = [AllowAny]`.
* [ ] Verify `get_queryset` filters by the requesting user or tenant, rather than filtering in the serializer or template.
* [ ] Verify `ModelSerializer` with `fields = '__all__'` does not expose internal or ownership fields.
* [ ] Verify serializer `read_only_fields` covers every field a client must not set, including `user`, `owner` and `is_staff`.
* [ ] Verify `@login_required` / `LoginRequiredMixin` is present on every non-public view, including class-based ones.
## Database & Row-Level Security
* [ ] Search for `.raw(`, `.extra(`, `connection.cursor()` and any f-string or `%` formatting inside a query.
* [ ] Verify `filter(**request.GET.dict())` or equivalent mass-filtering is not exposed — it lets a caller query relations you did not intend.
* [ ] Verify `order_by(request.GET['sort'])` is allowlisted.
## Web Frontend
* [ ] Search templates for `|safe`, `{% autoescape off %}`, and `mark_safe` in Python.
* [ ] Verify `json_script` is used for passing data to JavaScript rather than raw interpolation.
## Sessions, Tokens & Cookies
* [ ] Verify `SESSION_SERIALIZER` is the JSON serializer; the pickle serializer turns session tampering into code execution.
* [ ] Verify `SECRET_KEY` comes from the environment and differs per environment.
* [ ] Verify `SESSION_COOKIE_SAMESITE` and `CSRF_COOKIE_SAMESITE` are set.
## Object Storage & File Handling
* [ ] Verify uploaded files are validated by content, not by extension or the client-supplied content type.
* [ ] Verify `MEDIA_ROOT` is not served by the application in production, and that user uploads cannot be executed.
* [ ] Verify `FileField`/`ImageField` upload paths cannot be influenced by user input.
## Pre-Release Gates
* [ ] Verify `django-debug-toolbar` and `django-extensions` are not installed in production.
* [ ] Verify `pip-audit` or `safety` runs in CI and no known-vulnerable package ships.
## Backend & Delivery
* [ ] Verify `select_related` and `prefetch_related` are used on the querysets that render each page; the ORM makes N+1 effortless.
* [ ] Verify `django-debug-toolbar` or `nplusone` has been run against the real templates in development to count queries per page.
* [ ] Verify `CONN_MAX_AGE` is set so a connection is not opened per request, and is compatible with your pooling setup.
* [ ] Verify template fragment caching or the cache framework is used for expensive rendered sections.
* [ ] Verify `.only()` and `.defer()` are used where a view loads large columns it does not display.
* [ ] Verify `QuerySet.count()` is not called on large tables in a hot path when `exists()` would do.
## Measurement
* [ ] Verify `django-silk` or equivalent has profiled the slowest views against production-like data volumes, not a seeded fixture.
34 items · https://github.com/FarzamHabibi/pre-production-checklist · CC BY 4.0