13

I am working on a web application, security is high priority. So, if a user has failed to login more than 3 times, the account will be locked. Should I display a message to the user saying "your account has been locked"? It would help to attacker to get the username.

Simon
  • 3,182
  • 4
  • 26
  • 38
raj
  • 241
  • 2
  • 7
  • 1
    yes it is safe to show a prompt to the user about account locked information. –  Aug 17 '13 at 05:36

4 Answers4

14

While @Simon's answer is excellent, I would like to add one additional point. Do not lock out user accounts due to failed login attempts.

By doing so, you are introducing a huge DoS vulnerability in your application. Any malicious attacker can simply lock out a large number of your users by repeatedly failing the login process. You will also be introducing a large support headache because users will fail the login process. Sometimes repeatedly. Remember the third facet of the CIA triangle, Availability. Your application is useless if no one can use it.

Instead, what you should do is throttle the amount of login attempts allowed. Introduce a "time-out" period instead of permanently locking the user's account pending some action on the users part. This will sufficiently stop online bruteforce attacks while keeping the support emails and calls to a sane level.

  • 4
    Good lord yes. I spend a huge percentage of my time dealing with customers who get locked out of important services because automated attacks from China keep accounts effectively permanently locked. – tylerl Aug 17 '13 at 07:26
9

If you're getting a lot of password attempts, you need to lock out the attacker, not the victim. This should be obvious, but it's a pretty common problem anyway.

First of all, slow the attack. After even a single incorrect password attempt, the IP that sent the attempt shouldn't be able to submit another until several seconds have passed. You can mask this on the browser-side by displaying a "authenticating, please wait..." message. But on the backend, if you get more than one attempt in a single N-second span from a given IP, then return an error message that lets the attacker know you're not even going check to see if his guess was right.

For bonus points, require N seconds of silence, not just N seconds since the first guess. That way beating on the server only extends the timeout.

Second, block offending IPs, not offended accounts. You can easily extend your solution from the previous point to increase the wait time after N failed attempts. So for example, 10 attempts and you get an additional 15 minutes in the penalty box. You could even show a friendly countdown timer on your webpage. It's also helpful to tell people "3 tries left" so they think about what they type, and don't just hammer away on bad passwords till they get locked out.

Third, respond to attacks by making it less bot-friendly. If a single account is getting attention from hundreds of IPs, you change things around to break the bots. Put up a CAPTCHA challenge, for example. Real users may find it annoying, but not nearly as annoying as being locked out of your account.

tylerl
  • 82,225
  • 25
  • 148
  • 226
  • Throttling after a single failed password? That's pretty annoying for people who use a few passwords but don't remember which one they used. If you throttle after 5 bad passwords you still prevent brute force but legit attempts are likely to avoid throttling. – ThiefMaster Aug 18 '13 at 14:14
  • 4
    Throttling doesn't need to be intrusive to be effective. A 2 second hold-off is nearly imperceptible since actual humans will typically take at last that long to react to the error message and re-type their password. But it limits brute-force attempts down to a maximum of 30/minute and allows you to react quickly to a brute-force volley without maintaining a lot of state on your server. The cost is very low both to you and to your real users. – tylerl Aug 18 '13 at 21:15
8

You must tell the user that the account has been locked, otherwise I don't see how you would handle a such situation without displaying a message directly in the web application. Of course, you would most-likely send him an e-mail with some steps to unlock his account but still, you must notify the user within the application that you've sent him an e-mail.

Now, considering your main concern which is that an attacker could build a list of the registered usernames on your website, there is a solution to mitigate this problem.

Tracking attempts by cookies/hidden fields/database entries

Whenever a user attempts to login using a non-existent username, you could keep track of his failed attempt by storing the information in a cookie, a hidden field or even directly in your database. That way, if you would lock a real account after 3 failed attempts, you could keep track of the failed attempts (which aren't real failed attempts because the username doesn't really exist) and display the lock message exactly like in a real situation.

The most transparent and efficient way to implement this would be by inserting the failed attempts in a database because the user can always modify the hidden fields and the cookies, which could eventually help him to figure your little ruse. Also, it might be hard to keep track of the non-existent username attempts if the user tries many usernames by using cookies and hidden fields. However, in the database, you could simply log the user's IP, the non-existent username and finally the amount of failed attempts which would tell if you have to display the fake lock message or not to your web application.

You might also not want to filter attempts only by IP, in case the attacker uses a proxy and tests the very same username and notices that it took him again, for example, 3 attempts to lock the account. Again, he could figure out your ruse like this.

But, do you really need a such protection?

Before implementing a such protection, take some time to think if it is really necessary for your web application. A situation where this would be completely useless is a website that has a forum where users login using the very same username as the one displayed on the said forum. Obviously, a malicious user could build a list of the registered users quite easily simply by browsing pages.

Login using e-mail address

Have you thought of using the user's e-mail address to connect to your web application instead, if possible? It is far less likely that someone will attempt to build a list of e-mail addresses as there are way more possibilities than usernames (users tend to choose typical and simple usernames such as "Simon" when it is available. However, finding Simon's e-mail address is harder, as there are many possible e-mail services assuming he chose the username "Simon" on it again (e.g. Simon@gmail.com, Simon@hotmail.com, Simon@yahoo.com, etc.)).

Simon
  • 3,182
  • 4
  • 26
  • 38
  • I don't think your last paragraph really addresses this problem. There exist databases of known e-mail addresses; if an attacker is trying to find accounts on a site, they can absolutely try e-mail addresses that they already know exist. What's more, when they *do* find that an e-mail address has an account, that gives them much more information than a plain username would: `Simon` could be anyone, but `Simon@yahoo.com` can be correlated with other information known about the holder of that address. – ruakh Aug 17 '13 at 17:36
  • 2
    Don't track password attempts with cookies. That's just silly. Bots only track cookies that are useful to them, so that technique gets you nowhere. Storing attempts in the DB? Better, but not great. You can DoS yourself trying to keep up with the writes. The best solution is to use something like memcached. That's fast, shared, atomic, simple, and handles expiration automatically for you. It's 15 minutes to implement and the total performance impact on your app is near zero. – tylerl Aug 18 '13 at 21:21
1

Not showing error message doesn't add much value for security, while is a constant bad user experience, because it is very convenient to the user to know whats wrong with the login input. If your system require high security, you can use a timeout punishment system and a better password frame.