(Account Takeover via Reset Logic Abuse – Educational Case Study)
Disclaimer
This write-up is strictly for educational and defensive purposes.
All applications, endpoints, tokens, emails, and identifiers are fully anonymized.
No real user accounts were accessed.
The goal is to show how broken reset logic enables account takeover without changing passwords.
Why Password Reset Flows Are a Goldmine
Developers treat password reset as a secondary feature.
Attackers treat it as:
🔑 The primary door into accounts
Because password reset systems:
- Bypass login entirely
- Often skip MFA
- Are rushed features
- Are rarely threat-modeled
And most importantly:
You don’t need to reset the password to take over the account
Target Overview (Anonymized)
- Type: Consumer web app
- Reset method: Email link
- Flow:
- Request reset
- Receive reset link
- Open link
- Set new password
- Auth: Cookie-based session
Everything looked standard.
That’s what made it dangerous.
Phase 1: Mapping the Reset Flow (Never Skip This)
I requested a password reset.
Network traffic showed:
POST /api/auth/reset/request
Response:
{
"status": "RESET_SENT",
"reset_id": "r_9d3f"
}
🚩 Red Flag #1
A reset identifier (reset_id) returned to the client.
Phase 2: Inspecting the Reset Link
The email contained a link like:
https://example-app.com/reset?token=abc123
When opened, the browser sent:
GET /api/auth/reset/verify?token=abc123
Response:
{
"status": "VALID",
"reset_id": "r_9d3f"
}
So far, nothing alarming.
But then something important happened.
Phase 3: The Silent Session Creation
After clicking the reset link, the server set a cookie:
Set-Cookie: session=eyJhbGciOi...
😐
No password changed yet.
No confirmation step completed.
The user was already partially authenticated.
Phase 4: Testing What This Session Could Do
I checked basic endpoints:
GET /api/user/profile
Response:
{
"email": "victim@example.com",
"plan": "premium"
}
🚨
I was logged in as the victim
➡️ without resetting the password
➡️ without knowing the old password
This wasn’t a reset flow.
This was a login flow in disguise.
Phase 5: Why the Password Never Needed to Change
The backend logic was effectively:
IF reset_token_valid:
create_session()
Instead of:
IF reset_token_valid AND password_changed:
create_session()
That missing condition is everything.
Phase 6: Exploiting This Without Email Access
Here’s the truly dangerous part.
The reset token:
- Was long-lived
- Could be reused
- Was not invalidated after verification
That means:
- Any leaked reset link
- Browser history
- Email preview
- Log exposure
→ Permanent account access
Even if the victim never resets their password.
Phase 7: Cross-User Reset Abuse (Advanced)
I tested another scenario.
I requested a reset for Account A, got a reset token.
Then I modified the verification request:
GET /api/auth/reset/verify?token=abc123&email=victim@example.com
Response:
{ "status": "VALID" }
🚨
The reset token was not bound to a specific user.
That meant:
One valid reset token could authenticate any account
This is catastrophic.
Real-World Attack Scenarios
This bug enables:
- 🔓 Full account takeover
- 📩 No password change alert
- 🕵️ Silent persistent access
- 🔑 Bypass MFA entirely
- 📉 Zero failed login attempts
From the victim’s perspective:
Nothing looks wrong.
Why Monitoring Didn’t Catch It
| Defense | Why It Failed |
|---|---|
| Login alerts | No login occurred |
| Password change alerts | Password unchanged |
| MFA | Not triggered |
| Rate limiting | Valid token |
| Logs | “Reset verification” |
This is an invisible takeover.
Root Cause Analysis
❌ Developer Mistakes
- Treated reset verification as authentication
- Created session too early
- Reset token not bound to user
- Reset token not invalidated
- No step completion enforcement
This is state confusion, not crypto failure.
✅ How Password Reset Must Work
Non-negotiable rules:
- Reset token = authorization to change password only
- No session before password change
- Token bound to user + action
- Token single-use
- Token invalidated immediately after use
- New login required after reset
Anything else is exploitable.
How I Hunt Reset Flow Bugs (My Exact Playbook)
🔍 Checklist
1️⃣ Does reset link create session?
2️⃣ Can I access APIs after clicking link?
3️⃣ Is password change mandatory?
4️⃣ Can token be reused?
5️⃣ Can token be used for other users?
6️⃣ Does MFA trigger?
If any answer is “yes” — it’s broken.
Tools Used
| Tool | Purpose |
|---|---|
| Browser | Reset flow |
| DevTools | Session inspection |
| Burp Suite | Token manipulation |
| Logic | Always |
Severity Assessment
| Impact | Level |
|---|---|
| Account takeover | Critical |
| Stealth | Extremely high |
| Detection | Near zero |
| Abuse scale | High |
Severity:
Critical – Authentication Bypass
Why This Bug Is So Dangerous
Because:
- Victims never know
- Password remains unchanged
- No alerts are triggered
- Attacker access persists quietly
This is how long-term breaches happen.
Final Thoughts
You didn’t reset the password.
You reset trust.
And the system gave it to you for free.
