Hacker News new | ask | show | jobs
by aaaaaaaaaaab 1433 days ago
>In fact it might provide a similar kind of protection the physical chip provides for debit cards. Let me explain:

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.

1 comments

> You didn’t explain how this gives you any protection akin to a physical chip on a debit card…

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.

So you actually agree with me.

1. I don’t have any problem with OTP-based magic links, if they’re implemented carefully. As you’ve just demonstrated, a 6-digit OTP with 3 retries allowed is not sufficient at scale.

2. I’ve also demonstrated that OP’s proposal to augment the 6-digit code with a “secret” token gives you no additional security. It can only protect against someone peeking over your shoulder to snatch your OTP.

3. As you’ve just demonstrated, increasing the OTP length will mitigate the problem, as it increases entropy. For peace of mind, I’d recommend 64 bits of entropy, which can be achieved with a 13-letter alphanumeric code (case insensitive), or with 5 words from a dictionary of 10 000.

Seems like it :) but I would be more pragmatic and didn't bash the system for the reasons you brought up :)

ad 1 - IMO, it's still sufficient at scale with some basic infra. hardening

ad 2 - AFAIK the "secret" was never meant to protect from brute-force, but rather mitigate threats from actors controlling the email part

ad 3 - again, let's be more pragmatic - no one would use it if it required typing 13-letters OTP :) there are other ways to mitigate the potential attack you've described.

Best.

OP here… this was a great thread. Here’s a few takeaways, which you may not like, but I think are worth writing out.

1. This def needs hardening. I currently only use it for really low stakes stuff. I need to make that clearer in the README.

2. The next level of hardening I was planning on implementing is rate limiting code requests per email address. I figure I can step up the time-outs between code requests pretty aggressively to slow down brute forcing the code. The ATM that eats the card is a great analogy.

3. Maybe I missed it in the thread, but nobody mentioned that this from of auth makes it evident to the persons being attacked that something is happening if they have a bajillion code requests in their email inbox. There’s a lot of other problems that creates for these auth scheme, like filling a users inbox beyond its quota, triggering high volume breakers for SMTP relay services like AWS SES, etc. that wouldn’t be good.

For those watching, if you’re a security researcher feel free to open a GitHub issue on that repo and I’ll address it.