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.