A pentester found an IDOR in our statements API in 10 minutes. The fix was boring
Last quarter an external pentest found that any logged-in customer could download any other customer's account statement. It took the tester around 10 minutes. I want to share it because the bug was very ordinary, and ordinary bugs are the ones that survive reviews.
The endpoint was GET /api/statements/{id}. It checked that the request had a valid session. It did not check that the statement belonged to the customer in that session. Statement ids were sequential integers, so the tester downloaded their own statement, changed 48213 to 48212, and got a stranger's name, address and transactions.
How did it pass review? The authentication middleware was there, so it "looked secure". And the developer copied the pattern from an internal admin endpoint, where any staff user may see any statement. Same code, different authorization rule.
The fix:
select * from statements
where id = $1
and customer_id = $2 -- from the session, never from the request
If no row comes back, return 404, not 403. A 403 tells the attacker "this id exists, you just cannot have it".
What we changed in the process, which matters more than the fix:
- Every endpoint that takes an object id now has an automated test that logs in as user A and requests user B's object. One helper function, two lines per endpoint.
- Data access goes through repository functions that require the owner id as a parameter. You cannot forget it, the code does not compile without it.
- We did not switch to UUIDs as "the fix". UUIDs make ids harder to guess, which is nice, but ids leak in URLs, logs and emails. Unguessable is not the same as authorized.
We found 3 more endpoints with the same pattern in the week after, before anyone outside did. Check yours today, it takes one afternoon.
Written by
Fatima Al-Sayed
Application security engineer at a bank in Dubai. Threat modelling, auth flows, secure code review. I will ask where your JWT secret lives. Arabic coffee enthusiast.
Get the best of #security-theatre weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to comment