I spent four days for just hoping i got the vulnerability, i test the site with regular testing(like xss, sqli, scanning, prototype pollution, etc.) and brute force experiments.
During four days of testing I observed anomalous behavior, the website was extremely slow and unresponsive at certain times, and the other times it was perfectly fast.
Seeing those two behaviours, I ran login brute force tests during the slow periods and again during the fast periods.
and then i figured it was the server being overloaded.
So I tried brute force again during both the fast windows and the slow windows.
Press enter or click to view image in full size
At first I thought I was seeing things, but I validated the tokens against protected endpoints and they worked.
After finding out, it wasn’t magic. It was a TOCTOU race condition. In plain short the function that checks whether a login is allowed and the part that actually issues the token aren’t synchronized. If the auth function is slower than the incoming requests, multiple requests can slip past the check before the system updates state, so several different wrong passwords can all look “valid” because requests overtake the function’s internal timing.
Press enter or click to view image in full size
Imagine the login flow as two streets:
and
The code first walks down the check street and says “cool, this account looks allowed right now,” then walks down the use street and says “okay, I’ll create a session/token.”
If these two steps happen back to back, everything works perfectly.
But if the check step is slow (heavy CPU, slow DB, blocked I/O, overloaded server), multiple incoming requests line up behind it. They all get told “cross” by the initial check before the token-creation step finishes.
The result several requests reach the token-generation step even though the password validation should’ve failed.
In short:
when the auth function is slower than the incoming request rate, requests can overtake internal state and produce inconsistent results.