我已经获得了一些其他开发人员的代码,他们创建了一些登录安全策略。例如,如果您尝试使用数据库中存在的用户名登录,它将开始记录失败的登录尝试次数。然后在达到3次登录尝试后,它会在日志中添加另一个条目,但将第1位添加到LockedOut。
你们相信这是一个很好的安全政策吗?尝试获取条目的人不会尝试大量随机用户名并强行锁定所有人的帐户吗?这对安全来说似乎是一种糟糕的哲学。
我认为更好的安全程序是锁定任何根据跟踪各种用户尝试的IP表进行3次尝试的人,并在30分钟左右到期以防止DDoS。
你们如何设计登录安全性?这是开发人员基本上做的:
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.
编辑:最终程序:
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.";
}
}
答案 0 :(得分:2)
我不同意。我觉得完全锁定用户名更安全(不考虑IP)。
当恶意黑客伪造IP地址时会发生什么?黑客可以通过IP地址进行洗牌,并持续强制使用用户名。
我在三次尝试后锁定了15分钟。
对您的修改的评论:
我会做这样的事情:
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.
}
但是,我不会删除resolveTimeOuts()
中过期的IP请求。它可能会增加函数的执行时间。做这样的事情:
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.
}
这将导致resolveTimeOut()
的禁止执行,如果IP请求太快,则将删除所有过期的超时。对于DoS黑客而言,这是一种双重打击。他们获得了不同的页面,如果有大量过期,页面的生成可能会因deleteExpiredRequests()
而减慢。
编辑二: 这或多或少都是我要实现的。我会编写完整的代码,但我用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
}
您可以将humanRequest()
放入用户名验证的两种情况中。基本上,如果他们在短时间内请求任何用户名,黑名单就会列出。但是,如果您要在特殊页面中验证用户名(仅在某人尝试登录时包含该用户名),这将已经处理完毕。
这样,您只需要添加另一个表。无需修改您的表格。
答案 1 :(得分:2)
我所见过的两全其美的方法是在N登录尝试失败后在表单上使用Captcha。
这允许可能真实地忘记密码的真实用户继续尝试,尽管速度更慢,并且有效地停止自动暴力攻击。这使得攻击者正在使用多少IP无关紧要。
答案 2 :(得分:1)
我更喜欢在一段时间内限制登录失败的次数,然后暂时禁用用户或暂时拒绝接受来自该IP地址的进一步登录。
演习的目的是防止蛮力攻击。
答案 3 :(得分:1)
而不是进入我自己的个人哲学,我会尊重那些考虑适当安全的人,而不是其他人。
尽管如此,有一些指导方针和标准被认为是最佳做法。我建议从OWASP开始:http://www.owasp.org/index.php/Guide_to_Authentication
正常模式是在经过一定时间的一段时间后禁用用户以防止暴力破坏。我在编写良好的Web应用程序中看到的通常标准是3次无效尝试导致锁定1小时。
顺便提一下,OWASP网站上有关于锁定的具体问题:http://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Account_Lockout
引用文章(由我强调加粗):
如果攻击者能够猜到 没有帐户的密码 由于身份验证失败而被禁用 尝试,这提供了 受到袭击的机会 继续蛮力攻击 直到帐户遭到入侵。
自动执行暴力/密码 猜测对Web应用程序的攻击 是一个微不足道的挑战。密码 应采用锁定机制 如果超过,则锁定帐户 预设的登录次数不成功 尝试了。
密码锁定机制确实有 然而,逻辑上的弱点。它是 攻击者可能会尝试攻击 大量的身份验证 尝试已知的帐户名称 导致锁定整个块 应用程序用户帐户。
鉴于密码的意图 锁定系统是为了防范 蛮力攻击,一个明智的 策略是锁定账户 小时数。这显着 在允许的同时减慢攻击者的速度 账户是合法的 用户
答案 4 :(得分:1)
折衷方案是锁定一小段时间,以便大大减慢自动攻击速度,但对于发出“合法”错误的合法用户来说时间不会太长。恕我直言,在大多数情况下10秒就足够了,如果强制实施强密码政策。
答案 5 :(得分:1)
如果您为企业客户提供服务,则无法通过IP锁定用户。企业防火墙通常倾向于从Web服务器隐藏用户的IP地址。防火墙后面的任何三个用户的三次不成功尝试可能会锁定整个组织(或者一个真正愚蠢的用户,如果按下,他们从不检查他的大写是否锁定)。