Skip to content
>_ITDITDWeb Security Platform

By framework

Django security — DEBUG, SECRET_KEY, and authorization

Django has safe defaults, but incidents come from settings: DEBUG=True in production (settings/secret exposure), a leaked SECRET_KEY, and thin authorization. Set DEBUG=False, load SECRET_KEY from the environment, authorize explicitly. Defensive, no attack steps.

Published 2026-07-02 Updated 2026-07-02 4 min read

For: anyone running a Django app. No attack steps here — just keeping the safe defaults working while closing the gaps settings open. For the full picture, see the security-by-framework hub.

The big three pitfalls (they open in settings)

Django's defaults are excellent, but these three are yours to guard in settings and code.

① DEBUG=True in production

Error page exposes settings, env vars, secrets. Extracted via deliberate errors.

② Leaked SECRET_KEY

Basis for signing/sessions/CSRF. Leaks risk forging and tampering.

③ Thin authorization

Authenticated but missing permission/owner checks. ID swap reveals others' data.

The three holes most likely to open in Django — all outside the defaults/settings.

Also watch for SQLi via raw()/extra() or string interpolation, unsafe deserialization (pickle), unset ALLOWED_HOSTS, and unpatched dependency (pip) CVEs.

How to close them (3 steps)

1

DEBUG=False + ALLOWED_HOSTS in production

Ensure DEBUG=False in production and set ALLOWED_HOSTS correctly. Stop detailed errors from showing externally and configure static/media serving for production. Bake it into deploy and verify every time.
2

Load SECRET_KEY from the environment, keep it private

Don't put SECRET_KEY in code/repo — load it from an environment variable or secret manager. Keep it off public directories and DEBUG pages, and rotate promptly if leaked (→ keep secrets out of public directories).
3

Make authorization explicit and cut dangerous input paths

Don't stop at login (authentication); make permission/owner-scoped authorization explicit. Use the ORM/placeholders and avoid string interpolation in raw(), and don't restore untrusted data with pickle. Keep dependencies (pip) CVE-monitored + patched fast (→ what IDOR is).

Common (dangerous)

  • production left at DEBUG=True
  • SECRET_KEY hardcoded in code/repo
  • no authorization — "logged in = can view"
  • raw() string interpolation · pickle on untrusted data

Correct

  • production DEBUG=False + ALLOWED_HOSTS
  • SECRET_KEY from env, kept private
  • explicit authorization (permission/owner scope)
  • ORM/placeholders, no untrusted deserialization

This site's view: batteries included, but settings and authorization are on you

Django guards a lot by default, but production settings (DEBUG/SECRET_KEY/ALLOWED_HOSTS) and authorization are things you must get right per environment and per app. The incidents we keep seeing are less elaborate attacks than settings/operations patterns: "debug was open in production," "a secret was exposed," "there was no authorization." So the center of gravity is tightening production settings, keeping secrets private, and making authorization explicit. Not undoing the solid defaults is the crux of running Django.

FAQ

QIs Django a secure framework?
A

Django is 'batteries included' — ORM-based SQL protection, CSRF protection, template auto-escaping, and an auth system are standard. Configured correctly it's a solid framework, but incidents come not from the core but from settings. DEBUG=True in production, a leaked SECRET_KEY, and thin authorization recur less as Django-specific issues than as operational/settings problems.

QWhat's dangerous about leaving DEBUG=True in production?
A

With DEBUG on, the error page can show detailed internals — settings, environment variables, stack traces. An attacker can trigger errors on purpose to extract them. In production, always set DEBUG=False and configure ALLOWED_HOSTS correctly. Also stop detailed errors from being shown externally and review static/media serving for production.

QWhy is SECRET_KEY important?
A

SECRET_KEY is the key underpinning signed cookies and sessions, CSRF tokens, password resets, and more. A leak can lead to forging or tampering with those. Don't put SECRET_KEY in code or the repo — load it from an environment variable or secret manager, and rotate it promptly if it ever leaks. Also keep it from being exposed via a public directory or a DEBUG page.