Host Header Injection Guide

Learn how to abuse the HTTP Host header to bypass authentication, poison password resets, and manipulate URLs.

๐ŸŽฏ What is the Host Header?

The HTTP Host header specifies which website/domain the client is requesting. All HTTP requests must include it:

GET / HTTP/1.1 Host: example.com Connection: close

The Host header is used by servers to:

  • Determine which virtual host/application to route to (same IP, multiple sites)
  • Generate absolute URLs in responses (password reset links, redirects)
  • Validate requests against allowed domains
  • Configure SSL/TLS certificates
โš ๏ธ The Problem with Trusting Host Headers

Host headers are user-controlled. Unlike the TCP connection origin, attackers can forge any Host value. Many applications blindly trust the Host header to generate URLs, leading to vulnerabilities.

Attacker runs:

curl -H "Host: attacker.com" http://vulnerable-app.com/reset-password

The app generates reset link: https://attacker.com/reset?token=xyz (points to attacker's domain!)

๐Ÿ’ฅ Common Host Header Attack Patterns
1. Password Reset Poisoning

Attacker requests password reset with malicious Host header:

Normal: User clicks reset โ†’ email contains https://legit.com/reset?token=abc
Poisoned: User clicks reset โ†’ email contains https://attacker.com/reset?token=abc
Result: Reset link sends user to attacker's site, attacker captures token and resets victim's password
2. Cache Poisoning / CDN Exploitation

Inject malicious Host value into cached response:

Request 1 (attacker): Host: evil.com โ†’ Response cached with evil.com links
Request 2 (victim): Gets cached response with evil.com links
Result: Victims redirected to attacker or served malicious JS
3. URL Generation Bypass

Applications use Host header to build URLs in responses:

Code: $url = "https://" . $_SERVER['HTTP_HOST'] . "/api/resource"
Attacker sends: Host: attacker.com
Result: Response contains https://attacker.com/api/resource
4. Internal Hostname Enumeration

Some apps reveal internal infrastructure via Host header validation errors:

Error message: "Host 'attacker.com' not allowed. Valid hosts: internal-db.corp, cache-01.local"
Result: Attacker learns internal structure and hostnames
๐ŸŽฏ Advanced Host Header Techniques
  • Null byte injection: Host: attacker.com\x00legit.com (may bypass validation)
  • Port confusion: Host: legit.com@attacker.com (some parsers treat as attacker)
  • Whitespace tricks: Host: legit.com.attacker.com (substring match fails)
  • IPv6 notation: Host: [::ffff:attacker.com] (format confusion)
  • Double Host header: Send two Host headers; behavior is app-dependent
๐Ÿ›ก๏ธ How to Prevent Host Header Injection
  • Whitelist Validation: Hard-code expected hostnames; reject anything else
  • Use Absolute URLs: Don't rely on Host header; configure absolute URLs in config
  • Validate Hostname Format: Ensure Host matches expected pattern (domain.tld, IP:port)
  • Use SERVER_NAME: In PHP, prefer $_SERVER['SERVER_NAME'] (configured, not user input)
  • Reverse Proxy Config: Set fixed Host header at reverse proxy level
  • X-Original-Host Header: Verify only trusted sources can set this override
๐Ÿ“š Real-World Examples

GitHub (2014): Host header poisoning allowed attackers to inject malicious code into password reset emails

LinkedIn: Cache poisoning via Host header reflected in HTTP headers (leaked via shared caches)

Shopify: Password reset poisoning in merchant dashboard (bounty awardee: Ali Yazdani)

๐Ÿงช Lab Progression

Lab 00 - Password Reset Poisoning: Forge Host header to inject malicious reset link

Lab 10 - Weak Validation Bypass: Exploit substring-based Host validation to bypass security check