tags:

views:

188

answers:

7

What's the best way to prevent a dictionary attack? I've thought up several implementations but they all seem to have some flaw in them:

  1. Lock out a user after X failed login attempts. Problem: easy to turn into a denial of service attack, locking out many users in a short amount of time.
  2. Incrementally increase response time per failed login attempt on a username. Problem: dictionary attacks might use the same password but different usernames.
  3. Incrementally increase response time per failed login attempt from an IP address. Problem: easy to get around by spoofing IP address.
  4. Incrementally increase response time per failed login attempt within a session. Problem: easy to get around by creating a dictionary attack that fires up a new session on each attempt.
+1  A: 

Maybe you need implement CAPTCHA on your web forms.

Felix Guerrero
+1  A: 

There is an eternal tradeoff between security, availability and usability, which means that there is no perfect solution.

A decent tradeoff, depending on your situation, is to use option #1 with a captcha. Lock the account after three failed attempts, but allow subsequent login attempts if a captcha is correctly solved.

Thomas
+13  A: 

I like gmail's anti-brute force system a lot. It is based on "heat" that a user can accumulate, after the user has overheated they are prompted with a captcha. You can keep track of heat using a sql database. Heat is assigned to an ip address. It is 100% impossible to "spoof" a tcp connection over the internet becuase of the three-way-handshake, however proxy servers are plentiful and ip address are very cheap. Proxy servers are commonly used to send spam, you can check a blacklist and automatically prompt them for a captcha.

Each bad action against your system will update the heat table. For instance a failed login will accumulate 35% heat. Once the heat level is greater than or equal to 100% then the user is forced to solve a captcha. Solving a capthca will "cool down" that ip address. The heat table could contain a timestamp column that is set to the current time on update. After 24 hours or so the heat can return to 0.

reCapthca is the most secure capthca you can use.

Rook
+2  A: 

I've always been a fan of your option 3 - locking out or throttling a client based on its IP address. The other options are all more trouble than they're worth for the reasons you've stated.

Spoofing an IP address is possible, but it does not defeat this counter-measure. If you mean "spoofing" in the technical sense - forging the TCP packet header - then that won't do the attacker much good, because even if they guess the correct password they won't receive the response that tells them so. They could still use proxies, of course, but the number of proxies is limited. Even if an attacker has 1,000 working proxies at his disposal and you allow 10 attempts per IP that's 10,000 attempts. If you enforce any password complexity at all (such as requiring an alphanumeric password) then this won't be enough to guess much.

That alone should be enough to stop most script kiddies. If you are up against a more determined attacker you would probably have to implement some sort of site-wide monitoring which detects that there are many attempts being made (so there's probably an attack going on) and "locks down" in some way, eg. by using CAPTCHAs. I'm not a fan of using CAPTCHAs all the time - they're just more annoyance than they're worth.

Ultimately, it's up to the user to choose a secure password (though you can help them). If they've chosen "Password1" as their password then nothing you can do will stop a hacker from breaking into their account.

Evgeny
+1  A: 

I would also recommend using option 3. While it isn't as good against an attacker with a large number of proxies (or a bot net), I still think it is the best answer for most sites. (Gmail has different threats from most sites so needs different responses.)

A real world example:
A large online game that I'm involved in keeps track of how many failed login attempts come from every IP address in the past 5 minutes. The moment that any one IP address accumulates 5 bad login attempts (regardless of number of successful attempts), that address is blocked for 45 minutes.

Why this works
I sat down and determined that a highly intelligent hacker would be able to break an account with dictionary about 1 out of every 100 attempts (probably much worse). So, worse case scenario has an attacker break 1 account every 100 minutes (per IP address). For the threats against this particular site, this was sufficient protection. Our accounts really aren't worth that much. You need to determine (for your site) how much protection you need. You could extend the window to 30 minutes if you wanted to make it take 3 times as long if you needed.

Important Note
Do not reset counts (be it for solution 3 or the heat-map described above) upon successful login. If you do, the attacker will just try to hack 3 accounts, then log in successfully to some account they already control (theirs or an already compromised account) and will never be throttled.

Eadwacer
Doesn't a system like that mean that a person who knows the IP address of another user of the game can shut down the IP address through IP address spoofing?
Christian
@Christian: No, because TCP uses a three-way handshake to establish a connection and this can't be completed with a spoofed address because the attacker won't receive the server's ACK. (It will be sent to the bogus IP address rather than the attacker's real address.) Without establishing a connection from the spoofed address, the attacker will have no way to attempt login from that address.
Dave Sherohman
A: 

It depends on what you mean by "prevent".

If you don't want them wasting your bandwidth, the throttling, lockout, etc are viable options. There is overhead with heat-tables -- you have to create and maintain the logic, store and administer the "heat maps", etc, etc. I've also seen some ip geolocation based systems that throw up a captcha or alters its log in profile if a user tries to log in from a "distant" or "unknown" ip.

If you simply want to massively reduce the effectiveness of dictionary attacks, use a salt in addition to password hashes.

0concern
How would a salt and password hash reduce the effectiveness of a dictionary attack? Salting and hashing -- as far as I know -- are only useful for encrypting the password so that it isn't stored in plain text in the database. In the end, a poorly chosen password will still be vulnerable to a dictionary attack, regardless of whether it's salted and hashed before storage.
Kevin Pang
A: 

You could disallow passwords that contain dictionary words if you are programming for an application where security is really important. You don't have to allow QWERTY as a valid password.

Christian