(no title)
mszary | 3 years ago
1. Someone (anyone) initiates the login flow
2. The user record in a DB gets enriched with
- the 6-digit OTP (sent via email)
- the "secret" (shared with the initiating browser)
- the current session failed attempts counter (default: 0, max: 3)
- the total failed attempts counter since last successful login (default: 0, max: 20)
Let's assume that you've initiated the session (hence own the "secret"), but have no access to the OTP - you will always have 3 attempts to guess the OTP before the session gets reset (a new "secret" + new OTP). So after the 3rd unsuccessful attempt you start from scratch. And at that point other means of protection might come into play based on the second counter (throttling the auth. requests on the WAF/fronting server, blacklisting IP addresses, etc.)
The number of accounts you're targeting does not matter - in fact it may help other systems mentioned catch your malicious attempts sooner.
aaaaaaaaaaab|3 years ago
You didn’t explain how this gives you any protection akin to a physical chip on a debit card…
Let me illuminate the problem with a real-world analogy: this system is like me walking into a bank with a list of account names, and the bank issuing me debit cards for those accounts with random PIN codes, no questions asked. I’d have 3 attempts to guess the PIN, then the ATM swallows the card. Same as in OPs login system!
Still, don’t you think banks would be silly to do this?
>So after the 3rd unsuccessful attempt you start from scratch.
You don’t start from scratch. You do 3 attempts per user, period.
>The number of accounts you're targeting does not matter
It does matter. The entropy of their six-digit OTP is small enough that pwning at least one account from a pool of users is feasible. As I’ve shown above, the number of users necessary for pwning at least one account with 50% probability is log(0.5)/log((1 - 10^-[digits])^[attempts per user]). In our case digits = 6, and attempts per user = 3, which gives us ~231000 users. Which isn’t too many for a website.
mszary|3 years ago
In both cases you (an admin) control how many attempts you wish to accept before sacrificing the usability over security (temporarily disabling the card and forcing you to call the bank and disabling 6-digits OTP in favour of ie. 12-digits OTP).
Your real-world analogy is, this time, too simplified :) Let me counter-argument with my example:
You are in a a possession of 1 million user emails and request OTPs for all of them (let's assume no other security measures are in place). If you hit all of the 1M records with 3 attempts of OTP - according to my simple experiment - you might hit (on avg) 3.18 accounts.
Of course, in real life, your attack would be mitigated on other (non-application) level.
Please find my ugly code for that experiment: https://pastebin.com/S2ufabhU
PS. When OTP size is increased to 7 digits - the avg account hit drops to 0.33. For 8 digits - it drops to 0.02. (please mind I'm using lousy RNG :)
PS2. What I'm trying to emphasize is that there's nothing wrong with OTP-auth like this if properly implemented with other basic anti-bruteforce techniques. You could get "better" results with simple password spraying.