Skip to content

Host header injection

Many apps use the Host header (or X-Forwarded-Host) to build absolute URLs: email links, resources, redirects, canonicals. If they trust it without validation, the attacker manipulates it to poison password-reset links, the cache, cause SSRF or reach internal vhosts. The Host value is set by the client, so it’s untrusted input.

  • Password reset poisoning: the reset link points to the attacker’s domain → the victim clicks → the token leaks via Referer/the request to the attacker domain → ATO.
  • Web cache poisoning (if Host/X-Forwarded-Host enters the cached response; see the cache page).
  • SSRF / routing: reach internal vhosts or panels by name.
  • Information leakage and bypass of host-based controls.

The server generates, say, the reset link with https://<Host>/reset?token=.... If you change the Host (or add X-Forwarded-Host, X-Host, X-Forwarded-Server), the email the victim receives points to your server. Injection variants:

  • Change Host: directly.
  • Add X-Forwarded-Host: evil.tld (many frameworks prioritize it).
  • Double Host or Host: victim.tld:@evil.tld depending on the parser.
  • Dangling markup via Host when reflected in the page.
# Password reset poisoning
POST /forgot-password HTTP/1.1
Host: evil.tld
# or keeping the real Host but adding:
X-Forwarded-Host: evil.tld
-> the victim's email links to https://evil.tld/reset?token=VICTIM_TOKEN
# Check reflection (cache poisoning / XSS)
GET / HTTP/1.1
Host: evil.tld # does "evil.tld" appear in the response (scripts, links)?
# Internal vhost access
Host: internal-admin # does it route to an internal panel?

Confirm impact by checking whether the email/resource uses the injected host.

Burp Suite (modify Host/X-Forwarded-Host in Repeater), Param Miner for unkeyed headers.

Requests with Host/X-Forwarded-Host that don’t match expected domains; reset links to external domains; duplicate Host headers.

  1. Don’t build URLs with the request Host. Use a configured canonical domain.
  2. Allow-list valid hosts; reject (400) requests with an unexpected Host.
  3. Ignore X-Forwarded-Host unless it comes from a controlled trusted proxy.
  4. For reset, generate the link with the canonical domain, never the received Host.

Invalidate potentially leaked reset tokens, fix link generation, and review poisoned caches.

  • Password reset poisoning via host header has affected multiple frameworks and apps (including popular CMS and custom applications); a bug-bounty classic with ATO impact from reset-token theft.
  • Several platforms have suffered cache poisoning through X-Forwarded-Host.

CVEs/incidents in NVD (https://nvd.nist.gov/vuln/search) and GitHub Advisories (https://github.com/advisories).

  • Changing Host and adding X-Forwarded-Host/X-Host on reset tested.
  • Confirmed whether the email link uses the injected host.
  • Host reflection in the response tested (cache/XSS).
  • Internal vhost access / routing evaluated.