防范nginx代理下请求头伪造攻击需在入口处主动控制:严格校验host头、可信源解析x-forwarded-for、显式设置host转发、补充referer/origin校验及头部白名单,并禁用下划线字段解析。

防范 Nginx 代理下的请求头伪造攻击,关键是在请求进入后端前就完成可信校验与主动控制——不依赖客户端输入,不透传原始头部,而是由 Nginx 显式定义、过滤或覆盖高危字段。下面从四个最常被利用的头部切入,给出可直接落地的配置逻辑和注意事项。
严格校验并拦截非法 Host 头
Host 头是伪造攻击的“入口级”目标,用于劫持重定向、污染缓存、绕过租户隔离。防御核心是拒绝一切未显式声明的域名访问:
- 在
http块中定义一个default_server,监听 80/443,不设server_name,只加default_server标志 - 该 server 内仅写
return 444;(静默断连)或return 403;(明确拒绝) - 所有业务 server 块必须显式列出全部合法域名,例如:
server_name example.com www.example.com api.example.com; - 这样,
Host: 127.0.0.1、Host: evil.com或空 Host 请求,根本不会路由到你的应用,从源头阻断
安全处理 X-Forwarded-For 等 IP 类头部
X-Forwarded-For 极易被伪造,但它的“来源 IP”真实。关键是只信任你可控的上游代理(如 CDN、负载均衡器),其他一律忽略:
- 在
http块中用set_real_ip_from明确指定可信源 IP 段(如set_real_ip_from 192.168.10.0/24;或 CDN 提供的回源段) - 启用
real_ip_header X-Forwarded-For;和real_ip_recursive on;,确保多层代理时取最外层真实 IP - 反向代理配置中,统一设为
proxy_set_header X-Forwarded-For $remote_addr;—— 不拼接、不透传原始值 - 后端应始终使用
$remote_addr(已被 realip 模块修正)获取客户端 IP,而非读取原始$http_x_forwarded_for
主动控制 Host 头转发,禁用透传
当 Nginx 作反向代理时,proxy_set_header Host $host 是典型风险点。攻击者发 curl -H "Host: attacker.net" ...,后端若未校验,可能生成恶意跳转链接或错误日志路径:
- 推荐写法:
proxy_set_header Host $proxy_host;(即 proxy_pass 后指定的后端地址,如backend:8080) - 单域名后端也可固定为:
proxy_set_header Host backend.example.com; - 绝对避免:
proxy_set_header Host $http_host;或proxy_set_header Host $host; - 同步加固其他头部:
proxy_set_header X-Real-IP $remote_addr;、proxy_set_header X-Forwarded-Proto $scheme;,并用proxy_hide_header移除危险头(如 Server、X-Powered-By)
补充防护:Referer / Origin 校验与头部白名单
对敏感接口(如登录、支付、密码重置),可叠加来源验证,作为辅助防线:
- Referer 检查适合简单场景:
if ($http_referer !~ "^https?://(www\.)?example\.com") { return 403; },但注意它可被客户端篡改 - Origin 检查更可靠(尤其 API 接口):
if ($http_origin !~ "^https?://(www\.)?example\.com") { return 403; },适用于跨域请求且浏览器支持良好 - 如需精细控制,可用
map指令构建头部白名单,例如只允许特定User-Agent或Accept值通过 - 禁用下划线字段解析:
underscores_in_headers off;,防止X-My-Header被误当作x_my_header绕过校验











