Hello there,
I am Pratik Dabhi, a Bug Bounty Hunter and a Penetration Tester. Many of you may already know me, but for those who aren’t, please visit my website to learn more about me.
In today’s blog, I’m going to share an interesting bug I found last year that allowed me to take over user accounts by manipulating the password reset link. This vulnerability is called Password Reset Poisoning via Host Header Injection.
Whenever you forget your password, websites typically offer you a “Forgot Password” feature. When you use this feature, the website sends you a password reset link in your email. This link includes a unique token that allows you to reset your password.
However, the reset link itself is created by the server and typically includes the domain name (like https://example.com/reset?token=abc123
). But if the application relies on user-supplied headers (like the Host
header) to build this link, it can be manipulated.
This is known as Password Reset Poisoning. If an attacker can control the host in the reset link, they can hijack the reset link and take over other users’ accounts.
Like every bug bounty hunter, I start with reconnaissance. Recon is the most important phase because it helps you understand how the target application works and where potential vulnerabilities may exist.
Here’s my approach:
✅ Subdomain Enumeration
I used tools like Subfinder and Assetfinder to find all the subdomains of the target domain:
👉 target.com
This helps to map out the full attack surface.
✅ Wayback Machine URLs
I ran waybackurls to discover historical URLs. Sometimes older endpoints can reveal interesting behavior or vulnerabilities.
✅ Probing with httpx
I used httpx to check if the discovered subdomains were alive and what technologies they used.
✅ Manual Browsing
Finally, I always manually browse the site. Manual exploration often leads to interesting insights!
During my recon, I came across the account subdomain:
👉 https://account.example.com
On this subdomain, I found a “Forgot Password” page:
👉 https://account.example.com/en/cant-login
This page allows users to enter their email address to receive a password reset link.
I wanted to see how the password reset link was created and if I could control any part of it.
Here’s what I did:
1️⃣ Opened Burp Suite to capture the request.
2️⃣ Entered a test email address on the “Forgot Password” page.
3️⃣ Clicked the submit button to trigger the password reset process.
Burp Suite captured the POST request:
POST /en/cant-login HTTP/1.1
Host: account.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 46
[email protected]&action=forgot_password
I suspected the server might be using the Host
header to build the password reset link.
Why?
Because if the application is not validating the Host
header, I could change it to any domain I want. This means the password reset link sent to the user would include the domain I control instead of the real site!
To confirm my suspicion, I decided to manipulate the Host header using Burp Suite.
Here’s how:
1️⃣ In Burp Suite, I sent the captured request to the Repeater.
2️⃣ In the Repeater tab, I modified the Host header to a different domain:
Host: bing.com
3️⃣ I sent the modified request.
Shortly after sending the request, I checked my email. The password reset email arrived. But here’s the surprise: the reset link pointed to https://bing.com
instead of https://account.example.com
!
Here’s what the reset link looked like:
👉 https://bing.com/reset?token=abcdef123456
This proved the application was using the Host header in the request to build the password reset link — and it was not validating it at all.
Sure! Here’s the impact and mitigation written in more detail, without symbols or emojis:
Attackers can fully take over a user’s account by capturing and using the poisoned password reset link. This allows them to change the victim’s password and lock them out of their own account.
After taking over an account, the attacker can access any sensitive or confidential information stored in that account, such as personal details, financial data, or internal company information.
If attackers exploit this vulnerability, it can lead to a loss of trust from users, as well as significant damage to the company’s reputation, which can affect future business and customer loyalty.
Applications should not rely on the Host header from the user request when creating password reset links. Instead, they should use a secure, server-side configuration like SERVER_NAME to ensure the correct and trusted domain is always used.
If the Host header is absolutely necessary for some functionality, it should be checked against a list of trusted and known domains to ensure it has not been tampered with.
Conduct regular security testing, including penetration testing and code reviews, to identify similar vulnerabilities early and fix them before they can be exploited.
Thanks, everyone for reading:)
Happy Hacking ;)
Support me if you like my work! Buy me a coffee and Follow me on Twitter
Website:- https://www.pratikdabhi.com/
Instagram:- https://www.instagram.com/i.m.pratikdabhi
Twitter:- https://twitter.com/impratikdabhi