1

What are good ways to prevent distributed brute force attacks on my website?

I think (not sure. if someone can assure me, thanks!) my site is secure against normal brute force attacks as I am using following pattern to throttle continuous login attempts for a single username:

X = Failed Login Attempts
Y = Time, since the last login attempt, for which next login attempt will not be accepted (in minutes)

if X is a multiple of 5
Y = 2^(X/5)

This increases the time delay by some exponent of 2 for every next 5 wrong login attempts.

Then I thought to myself, what if someone tries to distribute this brute force attack over multiple usernames/accounts for a same password? O.O

My first instinct was to search the internet for common practices. I did search and found different solutions. Every solution has had its own cons whereas most of them were too complicated.

And then whaaam! This wild idea crossed my mind:

It doesn't matter if you provide wrong or right credentials, the login script will sleep for 1 second while verifying your credentials.

If I used this method, it would take approximately 14 hours to try a password on 50k accounts or vice versa and hence making the bruteforce little impractical.

Since this my first web app, I am barely confident if this method will be okay to use. I am not sure if it will cause too much serverload or if it is even, at all, safe. Does this method offer a good trade-off between time and resource cost, vs. added security?

If somebody can help me figuring out if this is the right method and help me imroving it and/or suggest a pratical method (in case this isn't okay), maybe I can offer you an additional cookie if we ever meet?

0

if you provide wrong or right credentials, the login script will sleep for 1 second while verifying your credentials

This would not be effective unless this sleep was executed across threads - i.e. this would not stop a parallel attack where an attacker makes multiple connections and executes simultaneous login attempts.

If you did make this delay span threads, then you would be introducing a choke point into your application. Say 1% of your users attempted to log in at the same time, the last user would then have to wait 500 seconds for their login to be completed.

Slowing down your whole application is not a good idea as this is creating a Denial of Service (DoS) or a reduced service for your real users.

what if someone tries to distribute this brute force attack over multiple usernames/accounts for a same password?

The way to prevent this is to make your application secure against Username Enumeration. Common ways attackers can enumerate usernames are:

  • After an incorrect login, if the login page displays that the username was incorrect rather than the username/password combination.
  • If the user registration page informs users that a username is already taken.
  • If the forgotten password page informs the user that the username entered was not found.
  • If any URLs are active for valid users (say my username is foo) such as www.example.com/user/foo.

There are ways to prevent user registration and forgotten password pages revealing whether a username is registered if the username is based on email address. Sometimes the ability to enumerate users it built into the design of the application and preventing this is not possible. e.g. in a webmail application all usernames are effectively public as Bob will advertise they have the account bob@example.com if they want people to email them.

As well as doing what you're doing with incorrect guesses at a valid user, I would also do similar for logins from the same IP. This will throttle the rate at which passwords can be guessed horizontally against different users. The artificial delay could kick in after 5 failed attempts from the same IP and the time could gradually be increased per attempt.

Although that does not fully protect you from a botnet, throttling separately on both IP and username repeated attempts will reduce the risk of brute force attacks.

If you want to practically fully mitigate the botnet brute force threat you can enforce a requirement for 2FA on all accounts. This could be done via a OTP sent via SMS.

  • The method you suggested would be ineffective against botnets. -_- Am I right? – ashu Jan 3 '15 at 10:19
  • Also, my app does have URLs for username. i.e., if username foo is valid, anyone can access http://example.com/user/foo. Is it a security flaw? – ashu Jan 3 '15 at 10:22
  • @ashu: It itself yes, however as you are throttling repeated attempts against the same username too the two defences should provide you reasonable protection. Re: URL. It is a security risk which is part of the design of your system. As said, with some systems user enumeration is an accepted risk. It is up to you if it is an acceptable risk for your system. – SilverlightFox Jan 3 '15 at 13:59
1

Bit late here but there are a bunch of suggestions here: https://stackoverflow.com/questions/479233/what-is-the-best-distributed-brute-force-countermeasure

A problem with "it would take approximately 14 hours to try a password on 50k accounts" is what if your legitimate user tries to log in after a bot net has put in 50k requests and has to wait the 14 hours? Not happy presumably.

0

Your method may be somewhat effective, but the biggest and most obvious flaw is that you are intentionally slowing down your application! It may be tolerable if your user base is going to be limited to a couple of friends, but if you're opening this application to the world, an intentional slowdown would be completely unacceptable from an engineer's point of view. One second may not seem like much, but for impatient users these days, every second counts. If you add on the time for the page to actually download and render, your load time for the login page could easily reach 3-4 seconds or more, which can feel like eternity when you're just sitting there waiting.

Plus, it would only be effective if you assume that every single user will choose a secure password, which is highly unlikely to be the case. Chances are, a good chunk of them will choose something simple and common, like 123456, password1, or password123 - and an attacker would almost certainly try these first. If they spend 140 hours trying the top 10 passwords on every account, I wouldn't be surprised if 5% of them get compromised, which is quite a substantial number.

A neater solution that many major sites now employ is to use a Captcha (the distorted text that you have to read and type in). After about 5 incorrect login attempts from a single IP address (regardless of account), you must solve a captcha to continue trying passwords. This is highly effective in stopping brute force because a brute-force script is going to be unable to solve the captcha.

No worries if you don't know how to generate captcha images - Google can do that for you. It is very easy to use; you just register your site with Google's (free) recaptcha program, copy a bit of code into your website, and Google will do the hard lifting. Here's a little tutorial on how to use it. What's nice is that lately they've been revamping it so it can now distinguish bots from people without requiring the distorted text at all.

An alternative solution is to simply block the IP address of users after a certain number of incorrect passwords, regardless of account, but the obvious downside of this is that if someone is brute forcing from a public network (a library, for example), legitimate users could be blocked. Personally I still think the captcha solution is the best, because it is highly effective in stopping brute force while having minimal impact on legitimate users.

  • blocking IP would be ineffective against a botnet. Wouldn't it? – ashu Jan 3 '15 at 10:20
  • @ashu That depends on your definition of "ineffective". If the botnet has a million computers, and you allow 5 tries per IP, then the attacker would have 5 million guesses. It'll certainly crack some accounts, but definitely not all of them. Unfortunately short of requiring a captcha at every login, I don't think any method is 100% effective against botnets. A diligent system administrator would notice an attack, figure out a pattern that distinguishes botnet traffic from normal traffic, and block it from the firewall. – tlng05 Jan 3 '15 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.