5

I've been reading suggestions to use time-consuming formulas for checking passwords from login attempts, so that repeated attacks will be slowed down.

Wouldn't it suffice to just sleep a bit in the function that does the password checking?

Simplified example:

function check_password($user) {
  usleep(1000);
  return crypt($_POST["password"], $user->password) == $user->password;
}
forthrin
  • 1,751
  • 1
  • 13
  • 21

2 Answers2

6

Slow hashing is meant to make the task harder for offline attackers, who could grab a copy of the database of hashed passwords. An offline attacker runs the hash function on his own machines. A delay on the server is good only against online attackers, who "try passwords" by sending requests to the honest server.

In practice you want both: some regulation mechanism to block online attackers (e.g. a delay, but preferably something a bit more complex to hinder attackers who try many passwords on many accounts in parallel), and a slow hashing (with salts) as a second line of defence, against attackers who could get a read-only view of the hashed passwords as stored on the server.

Tom Leek
  • 170,038
  • 29
  • 342
  • 480
  • 1
    Good point! How common are offline attacks and how common are online attacks? (If one or the other are very common or very rare) – forthrin Aug 21 '13 at 18:23
  • Purloined password hashes are rather common; they are the usual consequence of a successful SQL injection attack. Online attacks are very common on SSH servers because there are automatic botnets which try to replicate that way (I get several hundreds of attempts on my server every day, and that's the lot of just about every server in the world). Both kinds of attacks tend to occur in different world; i.e. you will get both, but not by the same attackers. – Tom Leek Aug 21 '13 at 18:35
1

To add to Tom's excellent answer, what you can do with an online service is add attack detection heuristics. You might decide that three failed paasword attempts in a 10 minute period will result in a 10 minute lockout, or a warning email to the account holder. You might flag multiple simultaneous password attempts that originate from more than two IP addresses or from more than two unique sessions. You can tar-pit the IP address of someone who seems to be over-fond of trying bad passwords. Or you might come up with a clever new strategy of your own.

Being on line lets you minimize the availability of your service to be a password-testing oracle. You may want to implement more than a simple delay.

John Deters
  • 33,897
  • 3
  • 58
  • 112
  • Do online attacks commonly come from the same IP, or do they distribute their attacks? If the latter is common, then an IP sensitive delay wouldn't make sense. – forthrin Aug 21 '13 at 18:18
  • They can come from either. You might have a kid who scripts a password guesser from one machine, or you might be facing a botherder who is sending a thousand guesses a second. Even so, a botnet is finite, and even the largest have no more than a few hundred thousand machines. It wouldn't take long for all of them to send three attempts at guessing. In server logs, I've seen zombie attacks come in groups of a dozen or so at a time. If you were to tar-pit them all, you make a botnet attack on your site more expensive, possibly sending them elsewhere. – John Deters Aug 21 '13 at 21:48
  • Precise answers like this with concrete numbers makes it much easier to make decisions! – forthrin Aug 22 '13 at 06:55
  • Good answer - you could decide to introduce an artificial delay after X number of failed logins in the last Y minutes. One check will count the number from the same IP or range, and another will count the number on the same user ID - if they're above the threshold then you can throttle further attempts, but as Tom mentions you would probably want some intelligence in there to prevent parallel requests from defeating your delay. – SilverlightFox Aug 22 '13 at 09:59