The other day, a company sent me a 2FA code which was only four digits long.
I'll admit, this weirded me out. Surely 4 is just far too short. Right? I think almost every 2FA code I've seen has been 6 digits long. Even back in the days of carrying one of those physical RSA fobs, 6 has been the magic number.
But why?
A 2FA code is meant to prevent a specific class of problem. If an attacker has got hold of something you are (your username1) and something you know (your password), you are still protected by something you have (your phone). Whether your second-factor is an app generating unique codes, a SIM card receiving SMS2, or a cryptographic enclave producing signed transactions - it doesn't matter. The attacker can use your password but won't get the unique second code.
Suppose you received a 2FA code that was a single digit. Is that secure enough?
I think most reasonable people would say that wasn't secure. An attacker has a 10% chance of guessing the 2FA. If the system allows for a couple of retries before locking them out, they've got a 30% chance of getting in.
Similarly a 2 or 3 digit code probably doesn't provide sufficient protection.
A typical bank card PIN is 4 digits. So an attacker has a 1 in 10,000 chance of guessing. That might be slightly better as bank PINs usually don't allow repeated digits, palindromes, and a few other combinations.
I suppose that if an attacker had compromised tens of thousands of credentials, and the service allowed for a few incorrect entries, it is statistically likely that they might be able to compromise a few accounts if they were only protected by 4 digits.
As 2FA codes get longer, they begin to reach the limits of what humans can remember. Yes, I know you have an excellent memory - but not everyone does. And I know your fancy 2FA app automatically copies and pastes the codes - but not everyone does. We have to work to what the average user is capable of at a minimum.
I think most people would find it annoying - if not impossible - to remember a 10 digit one-time password.
If you're copying a code from your phone to type into your laptop, there's probably an upper limit on what people will be prepared to do. No one is going to manually transcribe 128 digits. And, if they did, they'd likely introduce several errors.
So the industry has seemingly settled on 6 digits. I've ranted before about the lack of standardisation in the OTP specification. But all of them seem to allow 6 - 8 digits.
I suspect 6 is the standard because that's what the original RSA SecurID tokens used by default.
An attacker would have to be incredibly lucky to randomly guess a 6 digit code - literally a one-in-a-million chance3. Even if they had multiple retries, it's still statistically unlikely.
Once I logged in using my 4 digit code, I had full access to my account. But if I wanted to make any changes, I had to wait for another 2FA code to be sent. So I guess the effective length of code was actually 8 digits. Which seems excessive 🤣
Thoughts from the community
I asked my Twitter buddies for their wisdom:
Alex Hudson
@ealexhudson
Replying to @edent@edent Depends on retry/lockout policy? 4 digits is enough for a bank card, but there is a physical token involved there - is the account as valuable as that, though?Gut feeling is 6 digits is right for most circ*mstances though...
Rob Styles
@mmmmmrob
Replying to @mmmmmrob@edent 10,000 combinations is plenty to prevent guessing, and making the code longer doesn't add any additional protection if the message/device is compromised.Making the code longer makes the usability exponentially worse when the code has to be re-keyed.
Ryan Cullen
@artesea
Replying to @edent@edent Assuming just three retries before the code expires, 3 in 10,000 doesn't sound too bad. Also easy to remember whilst switching between the messaging app/notification shade and the app/website wanting it. I find with 6 I need to go back and forth. Worse with alphanumeric.
James Seconde
@SecondeJ
Replying to @mmmmmrob@mmmmmrob @edent For these sorts of reasons, this is why @VonageDev 2FA (Verify) lets you choose between 4 and 6 digits
Rhidian Bramley
@RhidianB
Replying to @edent@edent Zero digits. More user friendly and secure to send a hyperlink with a single use time limited encryption key. No heed to compromise usability vs security. Win win.
Chris Hill-Scott
@quis
Replying to @edent@edent Design System says 5 digits: design-system.service.gov.uk/patterns/confi…On Notify 2% of attempts are miskeyed – people with dyslexia probably disproportionately affected.
4 would be better – used by Airbnb and Uber – but you need stronger technical measures in place to prevent automated attacks.
What do you think?
- Traditionally, the something you are is a biometric. However biometrics are static - they never alter. So they're poor for some choices of authentication. A username represents something you are. Everyone can see your username - just like everyone can see the fingerprints you leave on every touchscreen and the DNA you shed all over the place.↩
- Let's gloss over SMS being a bit vulnerable for now.↩
- Although, as per Terry Pratchett: "Million-to-one chances crop up nine times out of ten.".↩