ALLOWED_HOSTS tells Django which Host header values it will accept. Django validates the header against that list whenever you call request.get_host(). You need it even if your web server already filters hosts, and reading the raw header yourself skips the check.
What the Host header attack is
A browser sends the host name it is talking to in the Host header, but a client can send anything. If an application builds links from that value, such as password reset URLs in email, an attacker can make the app emit links pointing at a domain they control. Validating the header against a known list closes that door.
What Django does
Per the Django security docs, Django checks the Host header against ALLOWED_HOSTS in request.get_host(). Set it explicitly:
ALLOWED_HOSTS = ["example.com", "www.example.com"]
The deployment checklist adds that the setting is required when DEBUG is False.
Two ways to bypass your own protection
- Reading
request.META["HTTP_HOST"]directly. The docs warn this skips validation. Userequest.get_host()instead. - Trusting
X-Forwarded-Hostwithout need. Django only uses it if you setUSE_X_FORWARDED_HOST = True. Enable that only when your proxy sets the header itself and strips client copies.
Do not rely on the web server alone
The docs say Django requires ALLOWED_HOSTS even if your web server validates hosts. Defense in depth is the point: config drifts, a second virtual host gets added, and a health check hits the app directly. Configure both.
Practical advice
- Use exact names, not a wildcard for everything.
- Include each real domain and subdomain you serve, and nothing else.
- Keep it in environment specific settings, since staging and production differ.
- Grep your code for
HTTP_HOSTandX-Forwarded-Host. - Build absolute URLs in emails from a configured site setting rather than the incoming request where you can.
Quick check
Is ALLOWED_HOSTS needed during development?
The checklist says it is required when DEBUG is False. Set it explicitly in every environment that is not your own machine.
Why not just validate hosts in nginx?
Do both. The Django docs require the setting regardless, and a second layer covers misconfiguration in either one.
Sources
Last reviewed: 19 October 2026.