Hijacking Accounts the Silent Way: A Deep Dive into Password Reset Poisoning

~Usman Mohamed, June, 5, 2025

Cyber Security Blogs >> Secrets In Code >>Hijacking Accounts the Silent Way
Every modern app has a “Forgot Password” button—it’s something we take for granted. But what if that simple feature became the weak link that lets someone walk straight into your account? During a recent security review, I explored a lesser-known vulnerability that flips the password reset process on its head. It’s called Password Reset Poisoning, and when exploited correctly, it can hand over full control of another user’s account—with zero interaction from the victim. Let’s unpack how this works, why it’s dangerous, and how developers can lock it down.

Why This Is a Big Deal

This vulnerability hinges on the way an application builds its password reset links. Ideally, when someone requests a password reset, the backend generates a secure token, ties it to the correct user, and sends it to their verified email. But here’s the catch: if an attacker can tamper with the request—say, by injecting a custom “Host” header or altering the URL—there’s a chance the app might build and send the reset link using attacker-controlled input. In the worst cases, that means: The reset token is delivered to the attacker instead of the real user The attacker clicks the link, sets a new password, and owns the account No alerts, no login prompts, no warning to the victim It’s a clean, quiet takeover.

Steps To Reproduce:

1. First the attacker enters the victim email address in forgot password page to send the forgot password link.
2. The attacker now captures the request of the forgot password.
3. The attacker now captures the request of the forgot password and then changes the URL in server parameter to send malicious forgot password link to the victim email address.
4. The attacker sends the request and so that it will send the malicious password reset link.
5. In the victim’s email account the malicious password reset link received.
6. Now the victim opens the malicious password reset link in the browser and because of this it redirects to the malicious website.
7. Whenever the victim clicks on that link. The Attacker can get the full token in his server for resetting the password of the victim.
8. The attacker form a proper URL with victim’s password reset token to reset the victims
9. The attacker can reset the password and log into the victim’s account.

How to Prevent This

Stopping password reset poisoning doesn’t require rethinking your entire app—just tightening up the parts that matter most. Here’s what works:

1. Ignore Untrusted Headers

Never rely on user-supplied headers like Host, X-Forwarded-Host, or X-Forwarded-Proto when generating links. These can easily be spoofed.

2. Hardcode Trusted URLs

Always use server-side logic to construct password reset links. Define trusted domains and protocols on the backend—don’t leave it up to client input.

3. Sanitize Inputs Rigorously

Even if your app logs data from headers, make sure it’s clean and not reused to build logic or responses. Better safe than sorry.

4. Verify Token Usage

Ensure tokens are single-use, expire quickly, and are bound to the user they were intended for. If a token is reused or used from an unrecognized source, flag it.

5. Add Monitoring

Log all password reset attempts and token usage. Look for strange patterns, like multiple resets in a short time or tokens used from new locations.

Conclusion

Password reset poisoning isn’t flashy—it doesn’t rely on fancy exploits or brute-force attacks. That’s what makes it so effective. It slips under the radar by abusing trust in processes that seem secure on the surface.

If you’re building web applications, don’t treat password reset flows as an afterthought. Test them thoroughly. Look at where your reset links are generated, how headers are handled, and whether the logic could be abused.

Account takeover doesn’t always look like a hack—it can start with a simple email and end with full access. Make sure your app doesn’t become the next cautionary tale.