11

In a web application, one way to protect against password guessing attacks is to lock out accounts after a set number of failed logins. This could be done on both source IP address and username.

For example, the following table shows what happens when repeated attempts are detected. The system is set to lock accounts after 3 failed logins within a 5 minute window, for 5 minutes.

IP             Time       Username           Creds Correct?  Message Given

203.0.113.1    10:00:00   [email protected]    N               Bad username or password
203.0.113.1    10:00:01   [email protected]    N               Bad username or password
203.0.113.1    10:00:02   [email protected]    N               Bad username or password
203.0.113.2    10:00:03   [email protected]    N               Bad username or password
203.0.113.1    10:00:04   [email protected] N               Login locked from your location
203.0.113.2    10:00:05   [email protected] Y               Welcome!
203.0.113.2    10:00:06   [email protected]    N               Account locked
203.0.113.2    10:00:07   [email protected]    Y               Welcome!
203.0.113.1    10:01:00   [email protected] Y               Login locked from your location
203.0.113.1    10:05:03   [email protected] Y               Welcome!

Login attempts only count when credentials are validated (the process is to check for lockout first before validating credentials - if locked then credentials are not validated).

As you can see from the following, a malicious user (at IP 203.0.113.3) can lock out an account causing a Denial of Service by repeatedly guessing the wrong password on purpose:

IP             Time       Username           Creds Correct?  Message Given

203.0.113.3    10:06:00   [email protected]    N               Bad username or password
203.0.113.3    10:06:01   [email protected]    N               Bad username or password
203.0.113.3    10:06:02   [email protected]    N               Bad username or password
203.0.113.3    10:06:03   [email protected]    N               Account locked
203.0.113.10   10:07:00   [email protected]    Y               Account locked
203.0.113.10   10:07:04   [email protected]    Y               Account locked
203.0.113.10   10:07:08   [email protected]    Y               Account locked
203.0.113.10   10:07:15   [email protected]    Y               Account locked
203.0.113.10   10:07:25   [email protected]    Y               Account locked

...preventing the real user at 203.0.113.10 from logging in.

An alternative to this is to artificially delay the HTTP response. Say first failed login delays by 1 second, the second by 2 seconds, the third by 4, and so on up to a total of 16 seconds. If their account is being attacked, the user will see a spinning circle in their browser while they wait for the HTTP response to their login request.

Are there any drawbacks to this? The above would now look like the following (say there is a 1 second delay as default, due to bcrypt iterations):

IP             Req Time   Resp Time Username           Creds Correct?  Message Given

203.0.113.3    10:06:00   10:06:01  [email protected]    N               Bad username or password
203.0.113.3    10:06:01   10:06:03  [email protected]    N               Bad username or password
203.0.113.3    10:06:03   10:06:08  [email protected]    N               Bad username or password
203.0.113.3    10:06:08   10:06:17  [email protected]    N               Bad username or password
203.0.113.10   10:06:18   10:06:35  [email protected]    Y               Welcome!

Note that the artificial delay (when active) is across threads, meaning the attacker cannot send requests from a single IP at any faster rate. A login from a different IP is not queued, although it will still experience any artificial delay built up via incorrect attempts on the username.

As you can see, the user at 203.0.113.10 is not denied access - they simply have to wait 17 seconds for their login to complete, while the attacker has to delay their attack. Therefore it is effective in preventing password guessing attacks.

My question is what are the negatives of this approach, and why don't you see this type of approach more often rather than the blanket lockout that can cause denial of service for users?

10
  • 2
    What happens if the attacker persists? Do they end up with a 1024 second delay (15 minutes) after 10 failed attempts? How is this substantively different than an approach that simply waits for 5 bad attempts and then locks for 5-30 minutes?
    – Jeff Meden
    Jun 11, 2015 at 16:07
  • @Jeff: No, it delays for a maximum of 16 seconds across threads. Jun 11, 2015 at 16:13
  • Maybe you can face a DoS if you have many threads in delay mode as an attacker can launch multiple login request at the same time.
    – r00t
    Jun 25, 2015 at 15:51
  • One reason is that the denial-of-service risk from deliberate incorrect logins appears to be a theoretical risk only, not something people are actually experiencing. I don't have info from megascale web firms (Facebook/Google) though.
    – paj28
    Jun 25, 2015 at 15:58
  • 2
    @paj28 that is not correct, I have seen this at non-megascale sites also - banking apps, auction and sale sites, even corporate systems...
    – AviD
    Jun 28, 2015 at 12:57

4 Answers 4

8

To turn your attack scenario through 90 degrees; consider the attacker who, instead of using a list of passwords against a single user, instead uses a single password against a list of users. Imagine I (as the attacker) don't care which account I get access to, I simply want access to any account (say, a bank account). Instead of trying to brute force a single user (which is likely to fail), I try the same password (a common one, say "CorrectHorseBatteryStaple") against a list of users that I've previously got hold of (most sites use email addresses for usernames, which aren't secret by any means).

In this scenario, you only get a single hit against each username, but you should still be throttling my attempts. Neither of your proposed defences protect against this scenario as is.

Your defences should be focused the other way, instead of throttling login attempts against a username, you should be throttling attempts against IP addresses. I believe Google does this at the moment. For example, if I lock out your account, you should still be able to login from your normal IP address (I.E. Different from the attackers).

5
  • The approaches described are using IP address too. The difference is that my approaches would not allow a login from another IP address if the account itself is currently locked/throttled. This was to mitigate against botnets trying accounts from different IPs. Jun 11, 2015 at 17:02
  • @SilverlightFox, Not quite. In your approach, an attacker outlined in my answer (I.E. Only tries once against each user name), would never be throttled. Since you're correlating attacks against a username, or both IP address and username, you'll never lock out this type of attacker. Jun 15, 2015 at 9:54
  • 1
    I believe it would because IP addresses are taken into account, regardless of username. That is, the system counts the number of failed logins from that IP in the last number of minutes. It also counts the number of failed logins against the username in the last number of minutes. Both these checks are separate. Jun 15, 2015 at 10:14
  • @SilverlightFox, Ok, then yeah, that would work. Jun 15, 2015 at 10:21
  • 3
    That will still be vulnarble against an attacket that both attacks different users and can change IP addresses rapidly (easy to do these days for example by using the TOR network). Not that I have any suggestion against this...
    – Tom Klino
    Jun 18, 2015 at 7:38
3

Drawbacks I see from this approach are:

  • More complicated to implement, especially over a scalable platform, cross thread.
  • May not be effective across load balanced servers.
  • Users may need to be patient.

For the above reasons it is not widely implemented.

2

I'm not sure why it'd be any more difficult to implement than locking the account, or why load balance rs would have any effect. Both approaches require centralized co-ordination about what to do (lock vs delay).

I think the main reason is that it's strange behavior, and makes your website look like it's broken (I don't think this is simply patience). Delays are common, and people are trained to think "the website is broken" because that's normally the case rather than "oh, it's just delaying my login because I typed in the wrong password", which is very unusual. In other words,everyone gets trained in what to expect in website behavior by the norms of how websites in general operate.

The other reason is really that people have a limited potential for simply re-retrying different passwords. If you've tried to login 10 times to a site and failed, you've forgotten your password at that point, and a 11th, 12th, and 13th attempt are unlikely to be of any use. Most people would give up at maybe 5-7. So at that point it's reset time, and waiting another 17 seconds isn't going to help anyone but an attacker.

7
  • 1
    "The other reason is really that people have a limited potential for simply re-retrying different passwords. If you've tried to login 10 times to a site and failed, you've forgotten your password at that point, and a 11th, 12th, and 13th attempt are unlikely to be of any use." I like this point, allowing any more than 1 attempt is basically a user comfort feature (because they probably are only going to fat-finger it once or twice), and the question becomes how much comfort do you want to afford them while still protecting from attackers. A pretty small number is usually sufficient.
    – Jeff Meden
    Jun 11, 2015 at 16:09
  • Well you could take the same approach but only start delaying after say 10 failed attempts. You could also implement something in the UI to say "Please wait: 8 seconds left...". Jun 11, 2015 at 16:50
  • @SilverlightFox And what's the point of delaying the login after they've already failed 10 times? That was the second point I was trying to make. Jun 11, 2015 at 16:53
  • Because it'll hinder a password guessing attack. Jun 11, 2015 at 16:54
  • 1
    @SilverlightFox The approach I used is to lock the user out for an hour, then 2 hours, 4 hours etc. That way the user has some time to remember the password, or come back to it later. In your case above the DOS attack would have to be IP specific, so it's unlikely to affect the user. The other problem with just using a delay is that an attacker with thousands of IP addresses can mount a serious attack, given they can try 5 times a minute per IP. If you lock them for an hour, or a day, per IP, that's significantly reduced. Jun 11, 2015 at 17:53
0

Your solution will depend on how variable the places the authorization system (AD, ldap, ...) is accessed from are.

Is the application you mention the only one to use the authentication service?

  • If yes: the throttling will work fine.You may have users which are surprised by the slowness of the application (as perceived by them) but this may not matter that much (your throttling should be strongly exponential so that the first 3-5 tries are almost the same, time wise, then put a steep delay curve)

  • If not: you need to make the same assumption for every system of concern. This may mean that some of the applications you do not control may not have the delay mechanism you mention in place. This also means that you must have a tight control over which applications use your authentication mechanism (which may not be obvious if it is exposed to, say, all your DMZ environments as a DMZ service)

I have a strong dislike for throttling in the case of applications because you must code it into the authentication mechanism (which should stay simple) or rely on firewall throttling. This is also because I usually have plenty of applications which query the authentication service from various places and the throttling is neither practical, nor enforceable. In that case you absolutely must have good passwords as they are prone to brute-force attacks.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .