Host Header Injection
Host header injection exploits applications that trust the HTTP Host header for generating URLs, routing, or access control decisions. The most impactful exploitation is password reset poisoning: the application uses the Host header to build the reset link, so an attacker-controlled Host value places their domain in the victim's reset email. Other impacts include web cache poisoning, SSRF, and virtual host routing bypass.
Password Reset Poisoning
Request a password reset for the victim while injecting your domain in the Host header. The application generates a reset link using your domain instead of its own. When the victim clicks the link, the reset token is sent to your server.
If vulnerable, the reset email sent to victim@target.local contains a link like: http://$LHOST/reset?token=abc123. Start a listener (nc -lvnp 80 or python3 -m http.server 80) to capture the token when clicked.
When the victim clicks the poisoned reset link, the GET request with the token arrives at your server. Use the token on the real application's reset endpoint.
Header Variations
If the basic Host injection is blocked, try alternative headers that some frameworks prioritize over Host.
Many frameworks (Laravel, Django, Rails) check X-Forwarded-Host before Host when behind a reverse proxy.
Other headers to try:
X-Forwarded-Host: $LHOSTX-Host: $LHOSTX-Forwarded-Server: $LHOSTX-Original-URL: http://$LHOST/forgot-passwordForwarded: host=$LHOST(RFC 7239)
Double Host Header
Some servers use the first Host header while validators check the second (or vice versa).
Duplicate headers are handled differently by web servers (Apache uses first, Nginx uses last). Test both orderings.
Port Injection
When the application validates the hostname but not the port, inject a port that includes your payload.
The @ character in the port field can trick URL parsers into treating $LHOST as the actual host in the resulting URL (e.g. http://target.local:@$LHOST/reset?token=abc).
Web Cache Poisoning via Host Header
If a cache sits in front of the application and caches responses keyed on the URL (but not the Host header), a poisoned Host value contaminates the cached page for all users.
Check for X-Cache: HIT or Age headers to confirm caching. If the response contains your injected host in links/scripts and gets cached, subsequent visitors load resources from your domain.
References
-
PortSwigger: HTTP Host Header AttacksTOOL: PortSwigger: HTTP Host Header Attacks, portswigger.net/web-security/host-header (opens in new tab)
Comprehensive guide on host header injection techniques.
-
PortSwigger: Password Reset PoisoningTOOL: PortSwigger: Password Reset Poisoning, portswigger.net/web-security/host-header/exploiting/password-reset-poisoning (opens in new tab)
Password reset poisoning via host header injection.