安全与风控
当应用信任 Host 头生成 URL、路由或做访问控制时…
适用于 Web 应用或反向代理信任 Host 头(或 X-Forwarded-Host 等替代头)来生成链接、路由请求或做访问控制的场景,用于测试密码重置投毒、缓存投毒、SSRF、虚拟主机绕过及各类 Host 校验绕过。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
当应用信任 Host 头生成 URL、路通用
解决思路
- 识别攻击面:确认应用是否将 Host 头用于 URL 生成(密码重置链接、邮件链接)、虚拟主机路由、缓存键、反向代理路由、访问控制决策或规范化 URL/SEO 重定向。
- 测试密码重置投毒:向 /forgot-password 发送请求,将 Host 改为 Burp Collaborator 域名(如 attacker-collaborator.burpcollaborator.net),提交受害者邮箱,检查 Collaborator 是否收到带重置 token 的请求。
- 测试拼接型变体:尝试 Host: target.com.attacker.com(链接变为 https://target.com.attacker.com/reset?token=xxx),以及 Host: target.com:@attacker.com(部分 URL 解析器会解析为 attacker.com)。
- 测试 Web 缓存投毒:发送 Host: attacker.com 的 GET / 请求,若缓存键只含 URL 路径不含 Host,则响应被缓存;再用不同 Host 发第二次请求,检查是否返回第一次的 Host 内容。
- 测试 SSRF via Host 路由:发送 Host: internal-admin-panel.local、Host: 127.0.0.1、Host: 169.254.169.254 等,观察反向代理(Nginx proxy_pass、Apache ProxyPass、K8s Ingress、云负载均衡)是否路由到内部服务或云元数据。
- 枚举虚拟主机:用 ffuf -u http://TARGET_IP -H "Host: FUZZ.target.com" -w vhosts.txt 爆破;并尝试特殊值 localhost、127.0.0.1、admin、internal、intranet;对比不同 Host 的响应大小与内容。
- 测试覆盖头绕过:同时发送 X-Forwarded-Host: attacker.com、X-Host: attacker.com、X-Original-URL: /forgot-password、Forwarded: host=attacker.com,因为 Symfony、Laravel、Django(USE_X_FORWARDED_HOST=True)、Rails、IIS URL Rewrite、Apache mod_proxy 等可能优先信任这些头。
- 测试请求行绝对 URI 覆盖:发送 GET http://attacker.com/path HTTP/1.1 配合 Host: target.com,利用 RFC 7230 规定(绝对 URI 时 Host 应被忽略)与代理/后端实现不一致。
- 测试双 Host 头:发送两个 Host 头(Host: target.com 与 Host: attacker.com),观察代理校验第一个而应用使用第二个、或服务器拼接为 target.com, attacker.com 的行为。
- 测试带端口/凭据的 Host:尝试 Host: target.com:@attacker.com、Host: target.com:evil.com、Host: target.com#@attacker.com、Host: attacker.com%23@target.com,利用 URL 解析器对 @ 和 # 的差异提取。
- 测试尾部点绕过:发送 Host: target.com.(DNS 视为 FQDN 等价),但字符串校验可能不剥离尾部点从而绕过白名单。
- 测试制表符/空格注入:发送 Host: target.com\tattacker.com 或 Host: target.com attacker.com,利用部分解析器按空白分割导致校验与应用取值不一致。
- 测试包裹值绕过:发送 Host: "attacker.com" 或 Host: <attacker.com>,应用可能剥离引号/尖括号而校验器不剥离。
- 针对框架特性测试:PHP 直接注入 $_SERVER['HTTP_HOST'](SERVER_NAME 仅在 UseCanonicalName On 时安全);Django 的 HttpRequest.get_host() 在启用时优先检查 X-Forwarded-Host 从而绕过 ALLOWED_HOSTS;Rails 的 request.host 信任代理后的 X-Forwarded-Host(Rails 6+ HostAuthorization 可缓解);Node/Express 的 req.hostname 在 trust proxy 下使用 X-Forwarded-Host 且无内置校验。
- 测试连接状态攻击:用 Burp Repeater 开启 Connection: keep-alive,先发一个 Host: target.com 的正常请求(代理校验并保持连接),在同一连接上再发 Host: evil.com 的请求,检查代理是否跳过后续请求的 Host 校验。
- 按决策树推进:先测直接 Host 注入是否反射到响应;若被校验则依次尝试 X-Forwarded-Host、X-Host/X-Original-URL/Forwarded、绝对 URI、双 Host、URL 解析器混淆、尾部点、空白注入、连接状态攻击;再测虚拟主机枚举、SSRF via Host 路由;最后检查服务端操作(邮件生成、webhook URL、API 回调)是否使用 Host。
- 利用 DNS 重绑定配合 Host 攻击:若可控 DNS,将自己的域名指向目标 IP,使 Host 头为自己的域名但请求打到目标服务器,用于绕过基于 IP 的访问控制。
适用边界 · 注意事项
- 目标应用完全不使用 Host 头(或替代头)生成 URL、路由或做访问控制,且无服务端操作依赖 Host 时,本技能无效。
- 缓存投毒要求缓存键不包含 Host 头;若 CDN/缓存将 Host 纳入缓存键(多数 CDN 如此),则无法通过 Host 投毒缓存。
- 连接状态攻击仅对只在 keep-alive 连接首个请求做 Host 校验的代理有效;若代理对每个请求都校验则无效。