开发者

Login Security Philosophy

I have been given some code of some other developer, who has created some login security policies. For example, if you try to login with a use开发者_StackOverflowrname that exists in the database, it will begin recording the amount of failed login attempts. Then after it reaches 3 login attempts, it adds another entry in the logs but adds the bit 1 to LockedOut.

Do you guys believe this is a good security policy? Wouldn't someone trying to gain entry just try a large number of random usernames and forcibly lock everyone out of their account? It seems kind of a bad philosophy for security.

I would think a better security procedure would be to lock out anyone who has made 3 attempts according to an IP table that tracks various user attempts and expires within 30 minutes or so to prevent DDoS.

How do you guys design your login security ?? Here's what this developer did basically:

if username is in database:
   if first login: increase fail-attempt counter.
   if second login: lock out username.
   else: don't let him in.
else:
incorrect password.

edit: Final procedure:

public void ResolveTimeouts()
{
    if (data.Expire <= DateTime.Now)
    { // it will only delete ONE single entry from the database, 
      // that happens to be this user's IP
      // If and only if, The expiration date is older than right now.
        Delete(this.data);
        data.Attempts = 0;
    }
}


int uid = UserExists(username);
if(uid < 1){
  ResolveTimeOuts(); // this will delete IPs from table if expiration passed
  if(loginAttempts >= 3){
    "Fail login, you have been locked out for " + TIMEOUT + " minutes";
    ExtendExpiration(TIMEOUT);
  } else {
    IncrementAttempts();
    "fail login, incorrect username or password.";
  }
} else {
  if(authenticate(uid, password)){
    "Successfully logged in.";
  } else {
    // INSERT lock out specific username feature here.
    "failed login, incorrect username or password.";
  }
}


I disagree. I feel like locking the username altogether is safer (without regard to IP).

What happens when the malicious hacker fakes an IP address? The hacker can shuffle through IP addresses and continuously brute-force the username.

I lock out after three attempts for 15 minutes.

Comments on your edit:

I would do something like this:

if(resolveTimeOuts()){ 
  bool uid = UserExists(); 
  //do other stuff
}else{ 
  "Your IP has been locked. Enter this code to prove you are human."
  // Captcha or math equation.
}

Though, I wouldn't delete expired IP requests in resolveTimeOuts(). It could increase the execution time of the function. Do something like this:

if(resolveTimeOut()){ 
  bool uid = UserExists(); 
  //do other stuff
}else{ 
  "Your IP has been locked. Enter this code to prove you are human."
  if(rand(1,5) == 5){
     // or something equivalent
     deleteExpiredRequests();
  }
  // Captcha or math equation.
}

This would give the fasted execution of resolveTimeOut() and if the IP is requesting too fast, all of the expired timeouts would be deleted then. Kind of a double-whammy for the DoS hacker. They get a different page and the generation of the page could be slowed through deleteExpiredRequests() if there is a large amount of expireds.

Edit two: This is more or less something I would implement. I would write the full code, but I program in PHP.

bool function humanRequest(){
    // decide if the request lag is humanistic or bot speed
    // for example: last_request > this_request - 500;
}

if(!humanRequest()){
    // redirect to a Captcha page or die with a warning or something (like SO does)
}
uid = getUsername(username);
if(uid > 0){
    // validated request
}
else{
    // increase attempts
    // you could have a separate column for IP requests or whatever
    // lock out username after 3 attempts
}

You could put the humanRequest() in a both cases of the username validation. Basically, if they are requesting any username within a short period of time, black list them. But if you are validating usernames in a special page (that only is included when someone is attempting to login), this will already take care of it.

This way, you only need to add another table. No need to modify the table you have.


The best-of-both-worlds approach I've seen is to use a Captcha on the form after N failed login attempts.

This allows the real user, who may have honestly forgotten their password the option to continue trying, albeit more slowly, and effectively stops automated brute force attacks. This makes it irrelevant how many IPs the attacker is using.


I prefer to limit the number of login failures over a period of time, then either disabled the user for a while or refuse to accept further logins from that IP address for a while.

The point of the exercise is to prevent brute force attacks.


Rather than get into my own personal philosophy, I'd defer to people who think about proper security and nothing else.

That said, there are certain guidelines and standards that are accepted as best practices. I'd suggest starting at OWASP: http://www.owasp.org/index.php/Guide_to_Authentication

The normal pattern is to disable the user after a certain number of attempts for a time period to prevent brute force. The usual standard that I've seen in practice in well-written web apps is 3 invalid attempts results in a lock-out of 1 hour.

By the way, the specific quesiton of lock-out is covered on the OWASP website here: http://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Account_Lockout

Quote from the article (bolding added by me for emphasis):

If an attacker is able to guess passwords without the account becoming disabled due to failed authentication attempts, this provides the opportunity of the attacked to continue with a brute force attack until the account is compromised.

Automating brute-force/password guessing attacks on web applications is a trivial challenge. Password lockout mechanisms should be employed that lock out an account if more than a preset number of unsuccessful login attempts are made.

Password lockout mechanisms do have a logical weakness, however. It is possible for an attacker to attempt a large number of authentication attempts on known account names resulting in locking out entire blocks of application users accounts.

Given that the intent of a password lockout system is to protect from brute-force attacks, a sensible strategy is to lockout accounts for a number of hours. This significantly slows down attackers, while allowing the accounts to be open for legitimate users.


A compromise would be to lock for a short period of time so to considerably slow down automated attacks, but not too long for the legitimate user who made a "legitimate" error. IMHO, 10 seconds could be enough in most cases, if strong password policy is enforced.


If you serve corporate customers, you can't lock users out by IP. Corporate firewalls usually tend to hide the users' IP addresses from the web server. Three unsuccessful attempts by any three users behind the firewall could lock out an entire organization (or one really stupid user who never checks to see if his caps lock if pressed).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜