一个晴朗的头攻下午,某电商平台的击漏安全工程师盯着日志文件,眉头越皱越紧。头攻攻击者没有用SQL注入,击漏也没碰暴力破解,头攻只是击漏悄悄改动了HTTP请求头里的Host字段,就让服务器把密码重置链接发到了自己的头攻邮箱。整条攻击链干净利落,击漏像一把钥匙捅开了本不该存在的头攻后门。
Host头攻击的击漏根源,在于服务器对“我是头攻谁”这件事过分信任。HTTP协议设计之初,击漏Host头只是头攻用来告诉服务器用户想访问哪个域名。但如今一台服务器往往托管着几十个站点,击漏反向代理、头攻负载均衡层层转发,每个环节都在默默依赖这个字段做路由决策。一旦某个环节直接拿Host头的值拼接URL、生成邮件链接或重置密码,漏洞就诞生了。
我见过最典型的案例,是某政府网站将Host头直接写入重置密码邮件。攻击者构造一个恶意请求,把Host改成自己的域名,服务器就乖乖地把带token的链接发到攻击者邮箱——而这个token能修改任意用户的密码。整个过程不需要任何高级技巧,curl命令加个-H参数就完事。更阴险的是,这种攻击还能用于缓存投毒,把恶意内容永久性地塞进CDN节点,让所有访客都中招。
为什么开发者总在这个坑里栽跟头?因为大多数人默认Host头是可信的,觉得它像TCP端口一样稳定。可实际上,Host头完全由客户端控制,连浏览器地址栏里的域名都能被伪造。更麻烦的是,有些框架会把Host头与内部服务器IP混淆,导致日志记录被污染,安全团队连攻击痕迹都追查不到。
别指望防火墙能拦住这类攻击——它长得跟正常流量一模一样。真正的防护得回归到代码层面。最直接的办法是配置Web服务器,只允许特定的Host值通过。比如Nginx里加一行server_name校验,Apache用VirtualHost白名单。反向代理层也要做同样的事,别让内部请求绕过规则。对于必须动态生成URL的场景,别用Host头,改用配置好的绝对域名常量。密码重置这类敏感操作,干脆把token绑定到用户会话,而不是依赖邮件里的链接参数。
有个细节很多人忽略:检查一下应用是否在响应头里反射Host值。如果返回的HTML或HTTP头里出现了你输入的Host内容,说明存在反射型漏洞,这通常意味着开发者把Host头当成了动态内容的一部分。这种反射点不但能用于钓鱼,还能配合浏览器解析差异搞跨域攻击。
最后说个土办法,但特别管用——部署时用脚本扫描所有代码,搜出所有引用HTTP_HOST或request.headers['host']的地方,逐个审计。安全圈有句话说得糙但实在:不信任输入,是写代码的第一戒律。Host头也是输入,凭什么例外?