Đây là một trong những bug bảo mật phổ biến và nguy hiểm nhất với Django. DEBUG = True bật ra hàng loạt hành vi chỉ dành cho dev mà bạn không muốn lộ ra ngoài.
Trang lỗi 500 sẽ hiển thị traceback đầy đủ kèm biến local — lộ SECRET_KEY, DB connection string, API key trong os.environ, payload request kèm password. ALLOWED_HOSTS bị bỏ qua nên bất kỳ Host header nào cũng được phục vụ, mở cửa cho HTTP Host Header Injection và cache poisoning. Django tự serve static file (chậm và sai layer — prod nginx mới đảm nhận). Mọi SQL query bị lưu trong connection.queries gây memory leak với app long-running. Email backend mặc định in ra console thay vì gửi thật — bạn tưởng đã gửi mà thực ra không.
# settings/prod.py — luôn luôn:
DEBUG = False
ALLOWED_HOSTS = ['example.com', 'www.example.com']
# CI/startup script kiểm tra:
if DEBUG and ENVIRONMENT == 'production':
raise RuntimeError('DEBUG must be False in production')Đừng tin câu "chỉ bật DEBUG vài phút để debug prod" — attacker scan liên tục, vài giây cũng đủ để leak SECRET_KEY.
- Cần debug prod thì dùng structured logging + Sentry, không bao giờ flip
DEBUG. - Production cũng phải bật
SECURE_*(xem [[#9260]]) để chốt thêm các lớp HTTPS, HSTS, cookie an toàn.
This is one of the most common security bugs with Django. DEBUG = True switches on many dev-only things:
- 500 error pages show the full traceback + local variables — leaking
SECRET_KEY, DB connection strings, API keys fromos.environ, request payloads with passwords. ALLOWED_HOSTSis ignored → any Host header is served → open door to HTTP Host Header Injection / cache poisoning.- Django serves static files → slow and wrong layer (nginx should serve static in prod).
- Every SQL query is kept in
connection.queries→ memory leak in long-running apps. - The default email backend prints to the console instead of actually sending → you think you sent but did not.
# settings/prod.py — always:
DEBUG = False
ALLOWED_HOSTS = ['example.com', 'www.example.com']
# CI / startup script guard:
if DEBUG and ENVIRONMENT == 'production':
raise RuntimeError('DEBUG must be False in production')Pitfall: Do not trust "just flip DEBUG for a few minutes to debug prod" — attackers scan constantly, a few seconds is enough to leak.
- To debug prod, use structured logging + Sentry — never flip
DEBUG. - Also set
SECURE_SSL_REDIRECT = True,SECURE_HSTS_SECONDS,SESSION_COOKIE_SECURE,CSRF_COOKIE_SECURE = Truein prod.