views:

46

answers:

2

I'm trying to block login for x minutes after y failed attempts. I'm already planning to log user logins, so I guess I could use the same database to calculate if blocking needs to happen.

My questions:

  • does it make sense to use the same logs table to run the logic of the y failed attempts blocking?
  • Some people have a table just for the failed attempts, and I heard they just increment the # of failed logins. This doesn't make sense since all they store is the number of failed attempts, not within what time period. 3 failed attempts in 10 minutes is not the same as 3 failed attempts in 3 days. Does the time span matter? Do you block after x failed attempts, period, or x failed attempts within a y time interval. And what's the best time frame for this?
  • can someone clarify the best practice approach to this?
+3  A: 

You need what's called a Password Attempt Window.

Basically 2 fields in the database, one LastPasswordAttempt (datetime) and PasswordAttemptCount (int)

Then on each login, check when the last LastPasswordAttempt occured and if it has been in the last say 10 minutes - increment the PasswordAttemptCount, otherwise reset it to 0 (or 1 because they've just failed).

In the same logic, check whether PasswordAttemptCount is equal to say 5 or more, if it is - deny the user access. You could have a 3rd field which locks them out for a few hours or a day.

i.e. CanLoginAfter(datetime) which you can set to a day from the last password attempt.

Hope this helps

Marko
Be wary about how you go about this. If you have a public site, with user interaction this can be used to maliciously lock people out of their own account by other people. Therefore either give the legitimate user some way of removing the lockout - email or whatever or use shorter times. Else you will have annoyed users sometimes.
I agree @MrXexxed - of course they would have to guess the username.
Marko
@Marjo Ivanovski indeed they would. Where a site uses email or a separate screen name to username that would be tougher, but there are still sites where the username is the screen name and in that case if it's a site where they post comments, posts or anything publicly it can be used against them. If not it's less of an issue anyway.
I completely agree. One solution would be to ask for the user's email after 3 subsequent failures - and lock them out if they fail to confirm it. What do you reckon?
Marko
+1  A: 

One approach would be to do this:

  • user_lockout: user_id, expires_dt (could be part of regular user table)
  • failed_login_log: user_id, dt (could be part of another log table)

Upon any login attempt for user_id, check to make sure expires_dt is in the past or NULL. (If in the future, the account is locked out.)

Upon a failed login, insert a record into failed_login_log and then do a count on the number of failed logins over the past X minutes (WHERE dt > DATE_SUB(NOW(), INTERVAL x MINUTES)).

If that count is greater than Y, update user_lockout.expires_dt to NOW() + Z MINUTES.

This allows you to lock an account out for Z minutes after Y failed attempts within X minutes.

konforce