当 Web 应用直接使用客户端请求中的 Host 头字段(如用于生成跳转链接、重定向、密码重置等),攻击者可通过伪造 Host 头注入恶意内容,导致密码重置劫持、缓存污染、SSRF 等安全风险。
本文介绍如何通过 Nginx 配置,严格校验 Host 头合法性,有效防御此类攻击。
⚠️ 漏洞原理简述
- • HTTP 请求中的
Host 头由客户端控制,不可信。 - • 若后端代码直接使用
$host 或 $_SERVER['HTTP_HOST'] 生成 URL(如:https://$host/reset?token=xxx),攻击者可构造:
GET / HTTP/1.1
Host: evil.com
导致用户收到形如 https://evil.com/reset?token=xxx 的链接,造成凭证泄露或钓鱼攻击。
✅ 修复核心思路:
在 Nginx 层拦截非法 Host 请求,仅允许预定义的合法域名通过。
✅ 方法一:使用变量标志位(推荐,逻辑清晰)
server {
listen 80;
server_name www.xlsys.cn;
# Host 头攻击防护 - Jack.Liu 2020.09.16
set $flag 0;
if ($host == "www.xlsys.cn") {
set $flag 1;
}
if ($flag = 0) {
return 403;
}
location / {
root /www/h5;
index index.php index.html index.htm;
}
}
🔍 说明:
set $flag 0; 初始化标志位。
若 $host 匹配合法域名,设 $flag = 1。
最终检查 $flag,非法则返回 403 Forbidden。
💡 此方法避免了 Nginx if 嵌套的陷阱,逻辑安全可靠。
✅ 方法二:支持多个合法 Host(多域名场景)
server {
listen 80;
server_name www.xlsys.cn;
set $flag 0;
if ($host ~* "^(www\.xlsys\.cn|www\.example\.cn|localhost)$") {
set $flag 1;
}
if ($flag = 0) {
return 403;
}
location / {
root /www/h5;
index index.php index.html index.htm;
}
}
或使用多个 == 判断(可读性更好):
set $flag 0;
if ($host == "www.xlsys.cn") { set $flag 1; }
if ($host == "www.example.cn") { set $flag 1; }
if ($host == "localhost") { set $flag 1; }
if ($flag = 0) { return 403; }
✅ 适用于:主站 + 子站 + 本地测试环境共存的场景。
✅ 方法三:使用正则表达式匹配(灵活但需谨慎)
server {
listen 80;
server_name www.xlsys.cn;
# 允许:www.xlsys.cn、IP 地址段、localhost
if ($http_Host !~* "^(www\.xlsys\.cn|134\.175\.\d{1,3}\.52|192\.168\.10\.\d{1,3}|175\.6\.\d{1,3}\.12|127\.0\.0\.1)$") {
return 403;
}
location / {
root /www/h5;
index index.php index.html index.htm;
}
}
⚠️ 注意事项:
使用 host,但更明确)。
正则需转义 . 为 .,避免匹配任意字符。
IP 段建议用 \d{1,3} 限制,但无法完全防止非法 IP,仅作示例。
不推荐在生产环境使用复杂正则,优先用精确匹配。
🧪 验证防护是否生效
curl -H "Host: www.xlsys.cn" http://your-server-ip/
curl -H "Host: evil.com" http://your-server-ip/
# 返回:403 Forbidden
📌 最佳实践建议
永远不要信任 Host 头:后端应用应使用配置文件中的固定域名生成 URL。
Nginx 层做第一道防线:即使后端有校验,Nginx 拦截可减少无效请求。
避免使用 default_server 返回敏感内容:确保默认 server 块返回 444 或 403。
日志记录非法请求(可选):
if ($flag = 0) {
access_log /var/log/nginx/host_attack.log;
return 403;
}
🌟 总结
通过在 Nginx 中对 $host 进行严格校验,可低成本、高效率地防御 HTTP Host 头攻击。推荐使用 方法一(标志位) 或 多域名精确匹配,避免复杂正则带来的维护风险。
安全无小事,从一个 Host 头开始加固你的 Web 服务!
阅读原文:原文链接
该文章在 2025/11/10 14:58:35 编辑过