views:

1058

answers:

10

As a response to the recent Twitter hijackings and Jeff's post on Dictionary Attacks, what is the best way to secure your website against brute force login attacks?

Jeff's post suggests putting in an increasing delay for each attempted login, and a suggestion in the comments is to add a captcha after the 2nd failed attempt.

Both these seem like good ideas, but how do you know what "attempt number" it is? You can't rely on a session ID (because an attacker could change it each time) or an IP address (better, but vulnerable to botnets). Simply logging it against the username could, using the delay method, lock out a legitimate user (or at least make the login process very slow for them).

Thoughts? Suggestions?

+21  A: 

I think database-persisted short lockout period for the given account (1-5 minutes) is the only way to handle this. Each userid in your database contains a TimeOfLastFailedLogin and numberOfFailedAttempts. When numbeOfFailedAttempts > X you lockout for some minutes.

This means you're locking the userid in question for some time, but not permanently.It also means you're updating the database for each login attempt (unless it is locked, of course), which may be causing other problems.

There is at least one whole country is NAT'ed in asia, so IP's cannot be used for anything.

krosenvold
I think this is the best solution. If you lock out an account for 5 minutes after 5 invalid attempts, you can only guess 1440 passwords per day. Yet you still don't have that much of a burden on the user if they forget their password, as they only have to wait 5 minutes.
Kibbee
You could also allow only 25 failure per day, after which they would have to call up and prove their identity, or request a password reset email. This would basically stop any chance of a brute force attack.
Kibbee
@Kibbe But you can be attacked by botnets that simply want to lock out all your users. Personally I don't thinky any permanent lockdown is good. You could of course detect that you're being attacked and change sitewide behaviour
krosenvold
+1  A: 

I think you should log againt the username. This is the only constant (anything else can be spoofed). And yes it could lock out a legitimate user for a day. But if I must choose between an hacked account and a closed account (for a day) I definitely chose the lock.

By the way, after a third failed attempt (within a certain time) you can lock the account and send a release mail to the owner. The mail contains a link to unlock the account. This is a slight burden on the user but the cracker is blocked. And if even the mail account is hacked you could set a limit on the number of unlockings per day.

Gamecat
+1  A: 

Do like most banks do, lockout the username/account after X login failures. But I wouldn't be as strict as a bank in that you must call in to unlock your account. I would just make a temporary lock out of 1-5 minutes. Unless of course, the web application is as data sensitive as a bank. :)

Bryan Denny
+1  A: 

You could add some form of CAPTCHA test. But beware that most of them render access more difficult eye or earing impaired people. An interesting form of CAPTCHA is asking a question,

What is the sum of 2 and 2?

And if you record the last login failure, you can skip the CAPTCHA if it is old enough. Only do the CAPTCHA test if the last failure was during the last 10 minutes.

kmkaplan
+1  A: 

A lot of online message boards that I log into online give me 5 attempts at logging into an account, after those 5 attempts the account is locked for an hour or fifteen minutes. It may not be pretty, but this would certainly slow down a dictionary attack on one account. Now nothing is stopping a dictionary attack against multiple accounts at the same time. Ie try 5 times, switch to a different account, try another 5 times, then circle back. But it sure does slow down the attack.

The best defense against a dictionary attack is to make sure the passwords are not in a dictionary!!! Basically set up some sort of password policy that checks a dictionary against the letters and requires a number or symbol in the password. This is probably the best defense against a dictionary attack.

Cervo
+2  A: 

You should implement a cache in the application not associated with your backend database for this purpose.

First and foremost delaying only legitimate usernames causes you to "give up" en-mass your valid customer base which can in itself be a problem even if username is not a closely guarded secret.

Second depending on your application you can be a little smarter with an application specific delay countermeasures than you might want to be with storing the data in a DB.

Its resistant to high speed attempts that would leak a DOS condition into your backend db.

Finally it is acceptable to make some decisions based on IP... If you see single attempts from one IP chances are its an honest mistake vs multiple IPs from god knows how many systems you may want to take other precautions or notify the end user of shady activity.

Its true large proxy federations can have massive numbers of IP addresses reserved for their use but most do make a reasonable effort to maintain your source address for a period of time for legacy purposes as some sites have a habbit of tieing cookie data to IP.

Einstein
+16  A: 

In my eyes there are several possibilities, each having cons and pros:

Forcing secure passwords

  • Pro: Will prevent dictionary attacks
  • Con: Will also prevent popularity, since most users are not able to remember complex passwords, even if you explain to them, how to easy remember them. For example by remembering sentences: "I bought 1 Apple for 5 Cent in the Mall" leads to "Ib1Af5CitM".

Lockouts after several attempts

  • Pro: Will slow down automated tests
  • Con: It's easy to lock out users for third parties
  • Con: Making them persistent in a database can result in a lot of write processes in such huge services as Twitter or comparables.

Captchas

  • Pro: They prevent automated testing
  • Con: They are consuming computing time
  • Con: Will "slow down" the user experience
  • HUGE CON: They are NOT barrier-free

Simple knowledge checks

  • Pro: Will prevent automated testing
  • Con: "Simple" is in the eye of the beholder.
  • Con: Will "slow down" the user experience

Different login and username

  • Pro: This is one technic, that is hardly seen, but in my eyes a pretty good start to prevent brute force attacks.
  • Con: Depends on the users choice of the two names.

Use whole sentences as passwords

  • Pro: Increases the size of the searchable space of possibilities.
  • Pro: Are easier to remember for most users.
  • Con: Depend on the users choice.

As you can see, the "good" solutions all depend on the users choice, which again reveals the user as the weakest element of the chain.

Any other suggestions?

bitschnau
I like the idea of using the password as an Acronym (or is it an initialism?!) for a sentence. Very smart! It would be simple enough to write a generator for them too..
sgargan
+4  A: 

I tend to agree with most of the other comments:

  • Lock after X failed password attempts
  • Count failed attempts against username
  • Optionally use CAPTCHA (for example, attempts 1-2 are normal, attempts 3-5 are CAPTCHA'd, further attempts blocked for 15 minutes).
  • Optionally send an e-mail to the account owner to remove the block

What I did want to point out is that you should be very careful about forcing "strong" passwords, as this often means they'll just be written on a post-it on the desk/attached to the monitor. Also, some password policies lead to more predictable passwords. For example:

If the password cannot be any previous used password and must include a number, there's a good chance that it'll be any common password with a sequential number after it. If you have to change your password every 6 months, and a person has been there two years, chances are their password is something like password4.

Say you restrict it even more: must be at least 8 characters, cannot have any sequential letters, must have a letter, a number and a special character (this is a real password policy that many would consider secure). Trying to break into John Quincy Smith's account? Know he was born March 6th? There's a good chance his password is something like jqs0306! (or maybe jqs0306~).

Now, I'm not saying that letting your users have the password password is a good idea either, just don't kid yourself thinking that your forced "secure" passwords are secure.

inxilpro
+4  A: 

You could do what Google does. Which is after a certain number of trys they have a captacha show up. Than after a couple of times with the captacha you lock them out for a couple of minutes.

Donny V.
+2  A: 

To elaborate on the best practice:

What krosenvold said: log num_failed_logins and last_failed_time in the user table (except when the user is suspended), and once the number of failed logins reach a treshold, you suspend the user for 30 seconds or a minute. It is the best practice.

That method effectively eliminates single-account brute-force and dictionary attacks. However, it does not prevent an attacker from switching between user names - ie. keeping the password fixed and trying it with a large number of usernames. If your site has enough users, that kind of attack can be kept going for a long time before it runs out of unsuspended accounts to hit. Hopefully, he will be running this attack from a single IP (not likely though, as botnets are really becoming the tool of the trade these days) so you can detect that and block the IP, but if he is distributing the attack... well, that's another question (that I just posted here, so please check it out if you haven't).

One additional thing to remember about the original idea is that you should of course still try to let the legitimate user through, even while the account is being attacked and suspended -- that is, IF you can tell the real user and the bot apart.

And you CAN, in at least two ways.

  1. If the user has a persistent login ("remember me") cookie, just let him pass through.

  2. When you display the "I'm sorry, your account is suspended due to a large number of unsuccessful login attempts" message, include a link that says "secure backup login - HUMANS ONLY (bots: no lying)". Joke aside, when they click that link, give them a reCAPTCHA-authenticated login form that bypasses the account's suspend status. That way, IF they are human AND know the correct login+password (and are able to read CAPTCHAs), they will never be bothered by delays, and your site will be impervious to rapid-fire attacks.

Only drawback: some people (such as the vision-impaired) cannot read CAPTCHAs, and they MAY still be affected by annoying bot-produced delays IF they're not using the autologin feature.

What ISN'T a drawback: that the autologin cookie doesn't have a similar security measure built-in. Why isn't this a drawback, you ask? Because as long as you've implemented it wisely, the secure token (the password equivalent) in your login cookie is twice as many bits (heck, make that ten times as many bits!) as your password, so brute-forcing it is effectively a non-issue. But if you're really paranoid, set up a one-second delay on the autologin feature as well, just for good measure.

Jens Roland