14

I want to cover the possible cases of attacking. My application already has captcha and two-factor authentication, but how can I avoid a tiny attack without annoying my users? The possible cases that I'm thinking to cover are:

  1. Show captcha after 3 failed login attempts based on Session, but the problem is that some related articles said it should not be based on ASP.NET session as it somehow could be cleared.

  2. Showing the two factor authentication after the captcha, but should I also show the captcha based on the failed count from the previous step? Or I should count from the beginning?

  3. Also I'm thinking of blocking the user's IP for a certain period but that might affect other users working from same IP! What if the hacker has a tool for changing the IP periodically?

Could you please advise me, with references if it is possible, what is the best way to cover these security issues?

9
  • You said that blocking might affect other users.How many users working from same ip?
    – dgn
    Commented Nov 18, 2014 at 8:48
  • 3
    @dgn It is quite common having multiple users using the same IP. Companies, Proxy, people sharing internet, ... IPv4 is just not enough. Commented Nov 18, 2014 at 9:12
  • 5
    OWASP brute forcing protection owasp.org/index.php/Blocking_Brute_Force_Attacks
    – void_in
    Commented Nov 18, 2014 at 9:24
  • 1
    @BobBrown Although this comment is out of the scope, but anyway this also to be considered if I have a lot of users got bifocals :) Commented Nov 18, 2014 at 14:21
  • 1
    in my experience you will get varying results blocking IPs for a brute force attack. I manage a number of wordpress sites and many (but not all) brute force attackers use an IP only once before switching. Clearly this is specifically to fight against IP blocking. I suggest you log failed attempts and monitor to see if whatever method you choose could use tweaking. Commented Nov 18, 2014 at 16:41

3 Answers 3

16

A relatively user-friendly way of mitigating brute-force attacks is delaying the minimum time between attempts. The first time your user enters wrong credentials, you let him wait 1 second before he can try again. The second time, you let him wait 2 seconds. The 3rd time, you make him wait 4 seconds. 4th time, 8 seconds, and so on. You also base this on the username that is used to authenticate, not any IP addresses. If there hasn't been an attempt in the past 5 minutes (or if the user authenticated successfully), you reset the counter.

The result is that a user that makes a typo in their password isn't affected the first few times, but any brute forcers will very quickly reach a point where brute-forcing is effectively not viable anymore.


Aside from preventing your web application against brute-force attacks, you should also ensure standard password protection practices like hashing & salting (preferably with PBKDF2 or bcrypt), secure password resetting, and mitigation against username enumeration. But I assume that, since you post on here, you already know that.

7
  • 1
    This is very good approach, I like it so much thank you. But also what if a hacker got list of my usernames and so he could try for each user until he reach the max delaying time? should I implement the other methods like captcha, etc.. Commented Nov 18, 2014 at 13:19
  • 9
    It might be a good idea to set a maximum limit or revert to captcha eventually, otherwise you can easily do a DoS against a particular user
    – watchowl
    Commented Nov 18, 2014 at 13:21
  • 1
    @Figo goncalopp brings up a correct point. I'd use a hard limit of 5 attempts every 5 minutes, but to scale up the delay before that.
    – Nzall
    Commented Nov 18, 2014 at 13:24
  • If you use a cool-down of 1 second, for a password length of 8 using only upper and lower case A-Z, you would have on average 847598 years until it has been brute forced (with a naive implementation). (26*2)^8 / 60 / 60 / 24 / 365 / 2 = ~847598 years
    – Matthew
    Commented Nov 18, 2014 at 16:41
  • 2
    -1 This approach is enabling denial-of-service attacks almost as bad as account lockout. If it only takes a request every 4 minutes to keep an account locked a single zombie could easily keep an attack against 1000 users going. First line of defence has to be IP based. Commented Nov 18, 2014 at 17:12
5

A good compromise between user experience and security would be to have IP-based captchas that trigger after a few failed logins from a particular IP, regardless of username.

  • This approach isn't vulnerable to DoS attacks against a single user by bruteforcing his account until the backoff time reaches several hours/days and prevents the legitimate owner of the account from logging in.

  • The number of people stuck behind a NAT isn't that high, and it's better to slightly degrade their experience with a captcha rather than prioviding attackers with the ability to completely DoS an account and lock out their legitimate owners.

  • It depends on what your app is for and how long the session lifetime is, but if it's something like Stack Exchange then people usually don't log in and out frequently.

As for your concerns about using sessions to track incorrect logins, you are right, that's pointless since it'll work for legitimate users, but an attacker won't even bother storing the session cookies which means on each try he'll get a new session and new login attempts without captcha.

For the IP changing, yes that's a bit of an issue, but an IP is still a cost to the attacker, eventually he'll run out of proxies and/or compromised machines in his botnet, and he will have to buy more. You should also always require a captcha if the IP is in an open proxy database (search for one on Google) or in the list of Tor exit nodes; that way an attacker won't be able to use these "free" solutions and will have to rent a botnet or some "premium" proxies that aren't yet in the blacklists.

1
  • Much appreciated for your great ideas. Commented Nov 19, 2014 at 11:30
0

I've been doing some research on mitigating brute force attacks and came across this post. I recently implemented the following approach:

In a 24 hour period: On 20 or more failed authentication attempts for a single IP address we require captcha for each subsequent attempt. At 100 failed attempts, we blackhole requests, but give no indication that the request was blackholed, we just keep returning the standard error message.

For us this is reasonable as we are not worried about large amounts of people logging in from the same IP and we believe our thresholds are high enough to where a normal user would not be affected. Its trivial to send an alert at 100 failures or if a username appears across multiple IP addresses.

We log everything in a database. We do concede that a botnet could use a large swath of IPs, however we log the username that an IP failed to authenticate with. This table is generally checked once per day so the potentially exists for us to identify a large scale brute force attack targeting a single user.

We also recently enhanced our password requirements to increase character length and complexity as well as not allowing passwords that are in various password dictionaries. Our login page is no-indexed in Google (not in robots.txt, use the meta robots tag as attackers can check your robots.txt for interesting pages). Finally, administrator accounts require two factor authentication.

Still, we accept the risk that a brute force hack is possible.

You must log in to answer this question.

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