To date, one of my most lucrative bug bounties came from a password reset poisoning vulnerability. This post walks through the process of finding, exploiting, and fixing this bug to help you earn a max payout in your own disclosures!
Password reset poisoning is a header based attack, where an attacker can manipulate the URL of a password reset link. Through adding or modifying HTTP request header values during an application’s password reset process, it may be possible to overwrite the domain of the link sent to the user:
Hi m8r0wn,Click the link below to reset your password:
https://<attacker-domain>/reset?token=123456789
Once clicked, the reset token is relayed to an attacker-controlled domain — resulting in account takeover.
- Navigate to the web application’s “Password Reset” page.
- Enter the name, username, or email of the target user’s account.
- Use a web application proxy (BurpSuite, OWASP-ZAP, etc) to intercept the request and modify the
Host:
header value to an attacker controlled address:
Don’t have your own server? Burp Collaborator links can help 🙂
POST /login/password-reset HTTP/1.1
Host: <attacker-domain>
..
{"email":"[email protected]"}
4. The user will receive a legitimate password reset email from the site. However, the link containing the secret reset token will show our modified header value:https://<attacker-domain>/reset?token=123456789
5. Once clicked by the user, the attacker can intercept the token and replay it’s value on the target application to successfully reset the victims password for full account takeover!
Host header not working? Try these techniques:
Double Host Header:
Depending on how the server reacts to duplicate Host
headers in the HTTP request, the malicious input may take precedence over the default:
POST /login/password-reset HTTP/1.1
Host: example.com
Host: <attacker-domain>
...
Test Override Headers:
Override headers such as X-Forwarded-Host
, X-Forwarded-Server
, X-HTTP-Host-Override
, and X-Host
can sometimes work to replace the Host
header value— resulting in successful exploitation:
POST /login/password-reset HTTP/1.1
Host: example.com
X-Forwarded-Host: <attacker-domain>
...
Why does this happen?
Password reset poisoning can occur when a website relies on header values to direct traffic or craft page links. If left unchecked, an attacker can inject their own values and modify the intended behavior of the application.
How to fix it?
The easiest approach, is avoid using header values to define site navigation. Request headers are not protected fields and can be modified by the user to inject malicious inputs. Additionally, performing Host
header validation and removing support for override headers such as X-Forwarded-Host
can be good mitigating strategies.
For more prevention methods, checkout the Preventing HTTP Host header attacks section of this article.
Thanks for reading! Connect with me on Twitter @m8r0wn and follow for more bug bounty tips. Happy hunting!