An Indian security researcher called Anand Prakash recently found a surprising flaw in Facebook’s password reset mechanism.
Simply put, he figured out an astonishingly simple way to reset anyone’s password by guesswork.
Fortunately, he reported the hole to Facebook, who very promptly fixed it, and sent him a cool $15,000 by way of thanks.
Actually, and technically, he didn’t use guesswork, which implies trying the most likely passwords first in case you run out of time or guesses.
He used a plain old brute force attack, where you try every possible password until you succeed.
At this point, you’re probably thinking, “Wouldn’t a brute force attack take too long?”
The answer is, “Not necessarily.”
A 14-character password, randomly chosen from A-Z, a-z, 0-9 and selected punctuations, has about twenty million million million million possible values (6414, or 284).
Even if you could try millions of millions of passwords a second, you’d never get through them all.
On the other hand, if your bank card has a 5-character PIN, and you (or a robotic key-pressing device) could enter one PIN per second, you could conceivably try them all in just over a day.
But the ATM will cancel your card, and then swallow it, if you make just three mistakes in a row, which means you can’t pull off a brute force attack, because the system shuts you out deliberately.
Password reset codes
Prakash noticed that Facebook’s password reset codes, which get sent to your email address or your mobile phone when you use the “forgot password” option, are six digits long, for a brute force “cost” of one million (106).
Trying 1,000,000 access codes, even across the internet, is perfectly feasible even if your network speed is modest.
So Prakash assumed that some sort of shut-out, known in the trade as rate limiting, was in force, and he was right: he couldn’t try more than about a dozen codes before either the number of guesses, or the elapsed time, or both, kicked him out and invalidated the reset attempt.
Trying all 1,000,000 reset codes was therefore out of question.
At least, brute force was no good when he accessed the Facebook pages via the usual domain name www.facebook.com.
Hackers are known for persistence, however, so Prakash tried other domains that were part of the Facebook empire, just in case Facebook had forgotten to enable rate limiting on a test site somewhere that had access to real data.
Both beta.facebook.com and mbasic.beta.facebook.com let him keep on guessing until he got in. (He used his own account to keep things legal.)
In other words, he’d just found a tiny security inconsistency with huge consequences: anyone could reset anyone else’s password, thus owning their account entirely.
What to do?
If you’re a web developer, never let your security guard down.
If you’re going to make test servers visible to the internet as a whole, and give them access to real data, they need to be at least as secure as your current production servers.
(Ideally, assuming that your test server setup will eventually replace your current configuration, test servers should be more secure than production: attacks only ever get better, so your security should, too.)
And, on the assumption that things will go wrong sometimes, get yourself into Facebook’s position: establish procedures that allow you to implement and ship security fixes quickly.
3 comments on “How one man could have broken into any Facebook account”
It is hard to believe Developers at FB missed out such a simple thing. I feel this was a backdoor as then an account be accessed. Thanks to Prakash, this backdoor stands exposed. Though I would not be surprised if there are other backdoors. Also storing email address /phone number in a format that can be retrieved by FB is the biggest backdoor by itself as anytime FB wants to access your account, all they need to do is replace your original email address/phone with something else they have access to.
To do away with this backdoor, FB should stop using email/phone numbers to retrieve passwords and instead use other alternatives where the password is not sent or generated using a personal identity but by a combination of identities that only the user knows but which is never stored on FB servers.
If FB is listening, I can help.
Facebook can already reset your password if it wants, on its own or anyone else’s behalf…and no one would be the wiser. So why use this particular trick as a backdoor, given that the behaviour of this “backdoor” can be externally observed verified. Surely they’d do it more deviously?
I think facebook’s other mistake was to have to few digits in their password reset codes. Bank card pin numbers need to be short because humans need to remember them, and type them in, but reset codes are almost never typed in, so they can be quite a bit longer without causing problems.
When I wrote a password reset system for another website a few years ago, the reset codes where 40 bits long, and expired after 24 hours, so rate limiting was not necessary because it would have been impossible to try out all trillion or so (10**12) different codes before they expired.
I also think that rate limiting can be relied on too much. It can be useful to slow down script kiddies, but only if an admin is monitoring the logs, and does something about it. I don’t think it would have much effect on it’s own against a determined attacker.
For example, it would be fairly easy to rate limit guesses against each account with a counter, but suppose the attacker does not care which account they compromise (They might want to spam timelines to push a fraudulent product), then they can try one password against every account on the system. The website admin might try rate limiting by IP address, but if the attacker controls a botnet they can make their password guesses from thousands or millions of different IP addresses.
The more sophisticated the attacker, the harder it becomes to pick out the cracking attempts from the general noise of web traffic, so what you relay need is some analytics that will graph all failed authentication attempts, so that if there is an uptick the site admins can investigate, and find a way to block the attack.