Defending web applications against dictionary attacks
Over at Reflective Surface, Ronaldo M. Ferraz discusses the usability of an authentication system that locks down an account for a certain period of time after three failed login attempts. Ronaldo sees this as a trade off between usability and security, but I see it more as an added security issue in that it allows malicious third parties to lock other user’s accounts armed only with their username.
The problem then is how best to defend web applications against brute force password guessing attacks without enabling denial of service attacks at the same time. The largest risk is from automated scripts that try every possible password until they get in. Identifying these attacks should be trivial—a real user could potentially fail a dozen or so times, but would be unlikely to try hundreds of combinations in quick succession. Assuming a malicious cracking attempt has been identified, what steps should a system take to foil the attack while still allowing the real user to access the site?
I can think of a few options, none of which seem like the ideal solution:
- Ban login requests from the attacker’s IP address. This introduces the usual problems with IP banning, namely the risk of banning a whole bunch of people indiscriminately but leaving the attacker free to skip the ban using open web proxies.
- Lock the user’s account and email them a warning of the attack and a special key needed to unlock the account again. This relies on the user having access to their email account when they next have a need to access the system. It also assumes that the user’s email account is secure, but since both the user’s password and the secret unlocking key will be required to access the system email security is of less importance (the user’s password is not sent with the unlock key).
- Send an automated alert to a system administrator so they can analyze the situation in real time and take any necessary action. This relies on administrators being available 24/7—hardly a safe assumption for most systems.
- After a certain number of failed attempts, challenge the user to “prove their humanity” with one of those obscured-text-as-image things. This comes with accessibility issues which have as yet been unresolved.
If anyone has any better solutions, please leave a comment.
(Sorry, didn't notice the note about using markup. Let's try this again. Feel free to delete the previous version of this comment.)
Combine, and refine.
#1: Banning the IP after so many attempts is useful, but I'd lean toward making that a temporary ban, maybe 5-30 minutes. And if there's any likelihood of more than one legit user sharing an IP (for instance, attacker has a dynamically assigned address, goes offline after failing to penetrate User Account A, then Legit User B goes online and is assigned the attracker's IP; or, more likely, attack comes from user on large network such as a school or corp, and every legit user behind that router ends up locked out because of one asshat's bad behavior), apply the ban only to the attacked account. So IP x gets locked out from Account y for z number of minutes.
#2: Emailing a warning of the attack is good, but if the attacker knows that an unlock code is going to automatically be delivered with it, doesn't this make the key vulnerable to packet sniffing? Though if the user is known to have a public key, the message can be secured in transit. As you pointed out, setting a unique unlock key for each attack raises other concerns. Using a key already known to the user (the "secret question") approach might be more effective. Though of course these secret questions often suffer from other vulnerabilities, like being too guessable/researchable.
#3: Yeah, but that's why redudant systems are preferable. Alert the user *and* the admin.
#4: The accessibility issues can be somewhat mitigated by making the lockout temporary; at worst, the user is inconvenienced by having to wait a while before getting back into their account. It's unequal access, but it's access. See if you can provide an alternate, accessible, means of expediting re-activation of the account (the secret question?)
Carina - 22nd January 2004 02:59 - #
My comment was long, so I posted it on my blog.
How Much Security is Needed?
Not all security measures are appropriate in all situations. You need to consider the value of the information being protected when designing a security system. Also, some novel approaches to preventing dictionary attacks.Adam Kalsey - 22nd January 2004 05:11 - #
Neil - 22nd January 2004 05:14 - #
Don't forget that hackers can spread their attacks across multiple usernames ... go get yourself a CDROM full of hotmail addresses, try to log in to each of them with the password "sexsex69". Eventually you'll stumble across someone that is using that password.
Then, just when you think you'll spot them by the pattern of IP+password, they could increment both username and password at the same time, all via proxies - pretty hard to spot that pattern.
However ... since legit users only need to login the once (per session), do they care if the login page seems kinda slow? No - the only people who care are those who are trying multiple logins serially. Therefore: just apply the delay Neil describes to every login attempt.
That only leaves the problem of parallel attempts...
Eric Scheid - 22nd January 2004 05:54 - #
Also effective is simply delaying the response to a login request with (in PHP) a call to sleep. Something like a 2-3 second delay shouldn't bother end users but will slow down an automated brute force attack to the point where it might take a very long to find a valid username / password combination. Depends to some extent on how the attack is being performed but with email warnings headed all over, should give enough time for self defence.
Harry Fuecks - 22nd January 2004 07:39 - #
Ben Thorp - 22nd January 2004 08:40 - #
Another method to detect Dictionary attacks (specifically) is to compare the new password attempt with the previous one. If it is higher (by ascii value) than the previous attempt on say 4 or 5 attempts, its a good indication that the submitter is running through a dictionary (they tend to be sorted in alphabetical order).
The chances a real user would get 4 or 5 password guesses in alphabetical order would be minute.
I havent implemented such a system as the thought has just occurred, but I suspect the code for it would be relatively trivial.
Richard Allsebrook - 22nd January 2004 09:02 - #
Beat Bolli - 22nd January 2004 09:03 - #
Another vote for the delay method. I was thinking of adding it to the PEAR Auth module, but the maintainers seem to think it would be too resource intensive to be of any use.
My proposition was to log all login attempts with a timestamp, and reject any attempt that occurs less than 2 or 3 seconds (configurable) apart from the last one.
I'm not sure the argument of ressource over-consumption is really that important : in the typical usage of a webapp, the login process is (most of the time) a one time process, and only a very small amount of the total ressource consumption.
Androse Rosewood - 22nd January 2004 09:09 - #
I wonder if you could get around the accessibility issues with text-as-image stuff by, essentially, posing one of those English comprehension questions from school. You know the sort of thing:
"Peter, John, and Mary were on their way home from school when they saw a bus pull into a sideroad, narrowly missing a pedestrian. The pedestrian was wearing a black coat and an identically-coloured hat. The bus sped off into the distance."
Please enter the colour of the pedestrian's hat: __________________
There are issues there with people not being able to understand English, but presumably the site would be in English -- a Spanish site would have a Spanish comprehension question. You'd have to have a reasonable stock of questions to avoid someone training a machine with the answers to all of them, but that's OK. Or, on a similar note, a question like "What colour is a London bus? If you don't know, you'll find the answer easily with a Google search." Again, you'd have to have a fair few questions, but if they are very easily Googleable then it wouldn't be taxing for a human, and would be very difficult to solve with a generic machine program.
sil - 22nd January 2004 09:21 - #
That's a stunningly good idea! I now feel obliged to nick it ;)
The only problem I see with it is the user feeling a bit put out if they don't understand the significance of their action. The fuzzy-text validation has a rough analogue in those little 'hidden number' strips that banks and credit card companies send you with your PIN number but I can see peeps having thoughts like...
"Ok, password is *******";
"What the hell is this? I'm off."
It's still a great idea though.Govan - 22nd January 2004 10:26 - #
Smiler - 22nd January 2004 11:36 - #
Ike Chambers - 22nd January 2004 11:39 - #
Hi Simon,
Your option 1 and what Carina commented on it seem to be the way to go.
I am running a site with lots of dynamic content and we have implemented something which controls the amount of pages a user can open with x amount seconds. If he opens more than y amount, he gets locked for 60 seconds with a short message (and a proper 503 HTTP-Respnse). He gets locked out based on IP, also the event gets logged. This also protects from bad-behaved webrobots that hammer away at your site. Saving bandwidth and saving traffic.
Having this system up for over a year, and judging from the logs, we only have had a single in the logs where only a single denied access was logged, in all other cases (several per week) you can see dozens of entried from the same IP in the same second (!) going on for quite some time. And that single case may also have been a robot shich just stopped immediately on the first 503-response, at least that user never complained.
If you are interested in the implementation, it was based on this code-snippet:
http://www.webmasterworld.com/forum88/119.htm
which I modified quite a bit to our needs.
Sencer - 22nd January 2004 13:45 - #
Lots of good ideas here. I think progressive throttling against a particular IP is a good idea. Some more ideas:
Password heuristics: if the password is close-but-no-cigar, do not treat the agent as a possible attacker.
IP heuristics: if the agent's IP is close to the IP used on the last valid login (say, the first two triplets match), do not treat the agent as a possible attacker.
Adam Rice - 22nd January 2004 15:34 - #
Aquarion - 22nd January 2004 20:48 - #
Aquarion - 22nd January 2004 20:48 - #
I recently came across the suggestion (sorry I don't remember where) to use math as a security question.
For example: "Enter the sum of 4 and 6:" or something like that.
Much simpler than telling a story and then asking for a minor detail. Imagine using a screen reader and hearing this pointless (it would seem pointless to the listener) story unfold. Even if the listener knows what the story if for, he/she has no idea which detail to listen for and may miss it. Using simple math creates much less confusion IMHO.
waylman - 23rd January 2004 19:08 - #
I helped design and implement the employee portal at the company I work for. The user's login from the outside is the user's network ID. We really haven't had very many problems with hackers trying to get into the system as it takes a very long time to login. However, we have had problems with disgruntled ex-employees locking out accounts of employees that they are unhappy with by simply logging in manually with a valid ID, but an invalid password. After three attempts the account is automatically locked out. This allows the ex-employee to create a Denial of Service (DOS) attack on the person that they are unhappy with.
If this is a valid user, the user can always call into a phone system to unlock and/or get a new password. Of course this requires that the employee enter their employee ID and part of their Social Security Number. If it is not the actual user who is trying to login then we track down the person and send them a letter from one of our lawyers. This has always been successful in stopping the ex-employee.
We have been toying with requiring the user to enter their employee ID as well as their network ID and password, or even setup an additional password. I really don't like any of these as it makes it more difficult to use the portal.
What do you think?
Tanny O'Haley - 24th January 2004 08:15 - #
Dave Van Even - 23rd February 2004 14:30 - #
Phil Yeo - 9th March 2004 11:30 - #
Another way to harden against this attack comes to my mind is to provide additional one step for verication.
After user is verified, system will bring user to a form in that user must copy a random words generated by system and paste it to input form and then submit. System then verify the the words that user submitted against the words it was generated.
But surely, it will reduce usability.
Nasir Simbolon - 6th July 2004 07:49 - #
use 2 passwords? That could never be brute forced really.
Personally I like to use Overkill in these situations so a system I recently made I have a graphic which tells the user to put in their password and then the number displayed in the graphic. Even assuming they OCR the graphic they will still have process that as well which would use a lot of processing power and slow down the attack.
Also when users register/change pass, do a check to be over 8 chars and make sure a number is present. I also perform a dictionary attack on their plain text password after figuring out the first 3 letters of any word used in the password (so to limit the number of comparisions performed).
Joe Wright - 14th December 2004 16:51 - #