September 13, 2026
Authentication Bypass lead to Account Takeover via IDOR
One Mistake Made Me Rich πΈ

By Abhishek (Bug Hunter)
2 min read
Introduction
Hello everyone! My name is Abhishek, and I am a Cyber Security Researcher and a bug bounty hunter at Bugcrowd with over five years of experience. Today, I want to share my favorite vulnerability: Account Takeover through the password reset functionality. I've written a blog detailing various methods to identify Account Takeover vulnerabilities, and today, I will introduce a new method that can lead to such vulnerabilities.
1: The hunt begins
Hiii everyone! π I found a web app with a totally normal signup flow β fill in your details, hit submit, and you're dropped straight into the app. Nothing screamed "vulnerable" at first glance. So naturally, I threw the usual suspects at it: XSS, CSRF, SSRF, and a pile of other small pokes. All quiet.
So I slowed down. Instead of chasing flashy payloads, I went methodical β scrolling through the entire Burp Suite history, endpoint by endpoint, specifically hunting for weak spots in the API authentication and authorization layer. That's where the real gold usually hides. π
2: The moment it clicked
Buried in a profile-update request, I spotted something juicy: sensitive account information sitting right there in the request and response bodies. And tucked inside it β a plain, boring, sequential database ID.
Here's the thing every bug hunter knows: the second you spot a raw numeric IDβ¦ you get ideas. π
3 : Testing the theory
Being a bug bounty hunter, when you see a numeric value, there's really only one move: make it someone else's. So I spun up a second throwaway account, hit the same profile endpoint, and grabbed its database ID too.
Simple. Just a 5-digit number, one digit off from the first account. No hashing, no obfuscation, no randomness β just 84213 next to 84212. So I had to ask: what happens if I just... swap them?
4 : Aaaand⦠it worked
I took Account A's profile-update request, replaced its database ID with Account B's, and fired it off.
Burp Suite β Repeater (illustrative, IDs redacted)
POST /api/v2/profile/update HTTP/1.1
Authorization: Bearer <account-A-token>
Content-Type: application/json
{
"accountId": 84213, // account A (mine)
"accountId": 84212, // account B (victim) β swapped
"email": "attacker@example.com",
"name": "Abhishek"
}POST /api/v2/profile/update HTTP/1.1
Authorization: Bearer <account-A-token>
Content-Type: application/json
{
"accountId": 84213, // account A (mine)
"accountId": 84212, // account B (victim) β swapped
"email": "attacker@example.com",
"name": "Abhishek"
}
One single click. Account B's name, email, and profile data got overwritten β including the email address, meaning I now controlled password resets too. That's not a bug. That's a skeleton key. ππ₯
π₯ ACCOUNT TAKEOVERπ¨ ZERO CLICKS FROM VICTIMπ EMAIL HIJACKED
5 : Why this actually happens
This is a textbook Insecure Direct Object Reference (IDOR), also known as Broken Object Level Authorization (BOLA) in the API world. The server checked that a valid, logged-in user made the request β but never checked whether that specific user actually owned the account ID they sent. Authentication passed. Authorization never got asked.
6 : Fix it before I find it
If you're building the backend for these endpoints, here's your homework:
π‘οΈ DEVELOPER CHECKLIST
Never expose raw, sequential numeric database IDs in requests or responses. Swap them for UUIDs or opaque, non-guessable tokens.
Enforce object-level authorization on every request β server-side, every time. Confirm the logged-in user actually owns the resource ID they're sending, not just that they're logged in.
Never trust client-supplied identifiers. Derive "who am I updating?" from the authenticated session, not from a field the client can edit.
Log and alert on cross-account access patterns β one account touching another account's ID is a five-alarm signal, not a footnote.
Bounty : Can't Disclosed.
Thanks for reading. Do not forget to give your review.