NGINX配置中$http_host引发云元数据攻击风险的解决求助
解决NGINX配置中的云元数据攻击漏洞(Host头相关)
问题根源
你的配置里有两处核心风险点:
- 反向代理环节使用了完全由用户请求控制的
$http_host变量 - 80端口的跳转逻辑同样依赖
$http_host,攻击者可通过伪造Host头指向云元数据IP,触发漏洞
仅替换反向代理的$http_host不足以彻底修复,必须覆盖所有用户可控的Host变量场景,同时添加Host头校验逻辑。
修复后的完整配置
server { root /var/www/test.abc.com/; index index.html index.htm index.nginx-debian.html; server_name test.abc.com; # 新增:直接拒绝非指定Host的请求,从入口阻断伪造Host头的攻击 if ($host != test.abc.com) { return 444; } location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; # 替换为固定域名,彻底抛弃用户可控的$http_host proxy_set_header Host test.abc.com; proxy_cache_bypass $http_upgrade; add_header Cache-Control no-cache; add_header Cache-Control no-store; add_header Cache-Control must-revalidate; add_header X-Frame-Options SAMEORIGIN always; add_header X-Content-Type-Options nosniff; add_header Set-Cookie "Path=/; HttpOnly; Secure"; proxy_cookie_path / "/; secure"; server_tokens off; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; } location ~ /\.git { deny all; } listen 443 ssl; ssl_certificate /etc/letsencrypt/live/test.abc.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/test.abc.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { server_name test.abc.com; listen 80; # 直接跳转固定HTTPS域名,不再依赖任何用户可控变量 return 301 https://test.abc.com$request_uri; server_tokens off; }
关键修改说明
- 替换所有
$http_host为固定域名:不管是反向代理的Host头还是HTTP转HTTPS的跳转逻辑,都使用硬编码的test.abc.com,彻底切断攻击者通过Host头控制请求目标的路径。 - 新增Host头校验:在443端口的server块中添加校验逻辑,直接拒绝所有非指定Host的请求,从入口阻断伪造Host的攻击尝试。
- 简化80端口跳转逻辑:删除原有冗余的
$http_host判断,直接返回固定HTTPS地址,避免任何用户可控变量的使用。
生效与验证
修改配置后执行以下命令使变更生效:
sudo nginx -t && sudo systemctl reload nginx
可以用curl测试伪造Host头的请求,验证漏洞是否已修复:
curl -H "Host: 176.544.122.111" https://test.abc.com
正常情况下会返回444(连接直接关闭)或301跳转到正确域名,不会触发云元数据访问风险。
内容的提问来源于stack exchange,提问作者Bilal Siddiqui
相关产品推荐
相关产品推荐

