当前位置:首页 > 休闲

目标url存在http host头攻击漏洞

我赌你站点里有个接口,目标直接返回了用户请求里的头攻 Host 字段。不信?击漏用 curl 带上一个伪造的 Host 打过去看看响应包。要是目标返回了 http://evil.com 这种地址,恭喜,头攻你中招了。击漏

这个漏洞叫 HTTP Host 头攻击,目标原理特别蠢——服务器信任了客户端给的头攻 Host 头,然后把它拼进重定向、击漏密码重置链接、目标或者静态资源路径里。头攻攻击者只需要改一下 Host 的击漏值,就能让受害者点开一封看似来自你官网的目标邮件,实际跳转到钓鱼站。头攻密码重置链接尤其致命,击漏因为很多系统直接拿 Host 拼完整 URL 发到用户邮箱。

我见过一个真实案例。某电商平台的“忘记密码”功能,请求是 POST /reset,服务端从请求头取 Host: shop.example.com,拼成 https://shop.example.com/reset?token=abc123 发邮件。攻击者把 Host 改成 evil.com,用户收到的链接就变成 https://evil.com/reset?token=abc123。只要用户点了,token 直接送到攻击者手里,账号秒被改密。整个攻击链没有任何漏洞利用技巧,就是改了个请求头。

更隐蔽的场景是缓存投毒。CDN 或者反向代理如果没校验 Host,攻击者可以污染缓存,让所有后续用户都拿到带恶意 Host 的页面。这时候受害者根本不用点邮件链接,正常浏览就中招。我测试过某新闻网站,用 Host: evil.com 请求首页,响应里所有 CSS 和 JS 的域名全变成了 evil.com。浏览器加载这些资源时,等于在攻击者的服务器上执行代码。

修复方法倒是不难,但很多人懒得做。最直接的是在应用层白名单校验 Host,只允许你配置过的域名。Nginx 里加一行 if ($host !~* ^(example\.com|www\.example\.com)$) { return 444; } 就能挡掉大部分。Java 的 request.getServerName() 也最好换成从配置中心读取的固定值,别信请求头。还有一点容易漏——如果你们用了 Spring Security,记得给 Host 头加个 HttpFirewall 校验,默认配置是放行的。

但说实话,我见过不少团队把修复优先级排得很低,理由是“内网系统”“没人攻击”。直到某天安全扫描报告里标红,或者等保测评被扣分才想起来补。麻烦的是,这漏洞不像 SQL 注入那样报错明显,它多数时候静默工作——攻击者拿到密码重置 token 后,不会立刻改你密码,而是先登录看看有没有其他价值。等你发现异常,往往已经晚了。

别偷懒。写个过滤器,三行代码的事。你要是用 Python Flask,直接在 before_request 里比对 request.host 和 app.config['ALLOWED_HOSTS'],不匹配就返回 403。五分钟改完,省得后面背锅。

分享到: