为何不能直接将Django的ALLOWED_HOSTS设为["*"]?2024年安全考量
关于Django Host头验证的常见疑问解答
为什么Django要承担Host头验证的责任?
Django官方文档提到:“即便在许多看似安全的Web服务器配置下,这类问题仍可能发生”“因为即便看似安全的Web服务器配置也易受伪造Host头攻击”
此前文档建议配置Web服务器验证HTTP Host头,虽仍推荐此做法,但许多常见Web服务器中,看似验证Host头的配置实际并未生效,比如Apache
Django接管这部分验证,本质是做安全兜底。很多开发者对Web服务器配置并不精通:
- 比如Apache的部分配置,看似限制了Host头,但受虚拟主机匹配逻辑影响,伪造的Host头依然能绕过验证;
- 多层代理(CDN、负载均衡)的部署场景越来越普遍,服务器的Host头验证规则可能被代理转发逻辑干扰,导致失效。
Django在应用层直接做验证,能避免因服务器配置失误或环境复杂度带来的安全漏洞。
2024年还需要担心“看似安全的服务器配置”吗?
答案是需要,原因有三点:
- 大量老旧服务器配置仍在使用,其中存在未修复的Host头绕过问题;
- 即便用新服务器,开发者也可能因配置失误写出“看似安全”但实际无效的规则(比如Nginx错误使用
server_name通配符,未正确限制Host头); - 云环境下的多层代理架构中,代理与后端服务器的配置配合容易出现疏漏,导致Host头验证失效。
能不能仅靠可靠代理做验证,将ALLOWED_HOSTS设为["*"]?
不建议这么做,理由如下:
- “可靠代理”也存在配置变更、人为失误的可能,一旦代理的Host头验证规则失效,Django层面没有兜底,会直接暴露伪造Host头的攻击风险;
- 如你补充的,SSL配置“捕获所有”的场景本身就有问题:比如Nginx的通配符SSL配置容易导致站点接收非预期流量,甚至可能被利用发起SSRF等攻击;
ALLOWED_HOSTS设为["*"]会让Django跳过Host头验证,一旦应用生成绝对URL(比如邮件链接、OAuth回调地址),可能会使用伪造的Host头,导致用户被引导到恶意站点。
内容的提问来源于stack exchange,提问作者Klaas van Schelven
相关产品推荐
相关产品推荐

