2009-07-31 131 views
3

我有一个登录系统需要用户名和密码。我想在一定数量的失败登录尝试后显示验证码。什么是实施这个的正确方法?我在这个网站上阅读过,有些解决方案建议在users表中添加一个'failed-attempts-count'。但是,我需要失败的尝试不被绑定到某个用户 - 即我希望显示验证码,而不管输入的用户名是否存在于系统中。将这个存储在一个会话变量是好的(我正在使用PHP)?如果是这样,那么根据需要向会话变量中引入数据是否没有缺点?我已经有网站上的每个访问者的任何会话ID(无论是否登录),所以我可以创建一个表,将登录尝试与此会话ID相关联......有关最佳/最安全方法的任何想法?谢谢。限制登录尝试,无论用户?

更新:从答案迄今为止,它看起来像会话ID是不是最好的办法,因为黑客可以简单地明确他/她的缓存(但是这是一个真正的问题,因为难道不这样减慢蛮力攻击足以使其无用?)。另一种选择是通过IP ......但我对内部网或代理下的用户犹豫不决,因为失败的尝试将被共享......我无法真正想到任何其他方法..你能吗?

回答

6

使用会话ID的危险在于,有人撰写蛮力攻击可以在每次尝试时清除自己的Cookie,从而为他提供新的会话。

请记住,可以使用浏览器之外的脚本语言编写自动化强力攻击,以便操纵为每个请求发送的Cookie。

另一种方法是创建一个包含用户源IP的表并在其中添加计数器。这会给使用代理服务器的用户带来不便。但至少你会发现那些试图反复猜测来自同一地点的密码的人。

更新:在连续的强力尝试期间清除cookie不会减慢攻击速度,因为此过程将自动化并几乎立即发生。这些类型的攻击中的Cookie操作相当普遍。修改cookie不同于清除浏览器的缓存(通常需要一段时间,因为它需要删除一堆文件)。所有攻击者需要做的是防止发送cookie。

1

如果黑客关闭浏览器并重新打开它,会话方法将不起作用,所以存储失败尝试次数和最后一次尝试次数的表(所以你可以检查是否说一个小时过去了你可以重置计数器)每个用户将是最安全的方式。

+0

没错,但我认为首先考虑验证码的想法是阻止自动化的暴力攻击..所以在每次尝试解决问题后都不会关闭浏览器或清除缓存? – oym 2009-07-31 09:24:23

1

您可以使用IP和时间记录所有失败的尝试。旧的失败尝试会在一段时间后被删除,如果有一定数量的失败尝试给定IP,则显示验证码。

1

安装APC http://www.php.net/apc或内存缓存(d)http://www.php.net/memcache或这里http://www.php.net/memcached(内存缓存也需要一个memcached服务器进行安装,在这里看到http://www.danga.com/memcached/),然后使用适当的增量坏的登录尝试从一个IP地址用的超时命令无论套房(5分钟,30分钟等)。这将允许您快速确定是否发生了暴力尝试(无需担心竞赛状况),并在确定的时间量之后自动终止该块。

APC例如:

$max_attempts = 5; // max attempts before captcha 
$attempts = apc_fetch('login_attempts_'.$ip)); 
if($attempts and $attempts>$max_attempts){ 
    // block code here or redirect, captcha etc... also suggest a short sleep time to delay answer, slow down bot 
}else{ 
    // check login here, run next code if login fails 
    if($login_failed){ 
     if(!$attempts){ 
      apc_store('login_attempts_'.$ip,1,$timeout); 
     }else{ 
      // function NOT currently documented on php.net, increments number stored in key 
      apc_inc('login_attempts_'.$ip); 
     } 
    } 
} 

当然这是一个非常粗略的例子...但你有想法

0

你可以得到的最准确的信息是他们的IP地址。如果您希望它是准确的,请不要使用会话cookie,因为用户可能会忽略您的会话cookie(即使用curl)。但是,如果您担心共享ips,您可以尝试包含其他信息,例如浏览器代理或使用ajax来传回您无法获得的其他信息。但是,除IP地址以外的其他所有内容都可能被伪造(即使这样,您也可以使用代理服务器)。