Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 限制登录尝试而不考虑用户?_Php_Security_Codeigniter - Fatal编程技术网

Php 限制登录尝试而不考虑用户?

Php 限制登录尝试而不考虑用户?,php,security,codeigniter,Php,Security,Codeigniter,我有一个需要用户名和密码的登录系统。我想在一定数量的登录尝试失败后显示验证码。实施这一点的正确方式是什么?我在这个网站上读过很多文章,一些解决方案建议将“失败尝试计数”添加到用户表中。但是,我需要将失败的尝试不绑定到某个用户-即,我希望显示验证码,无论输入的用户名是否存在于系统中。将其存储在会话变量中可以吗(我使用的是PHP)?如果是这样的话,仅仅根据需要将数据放入会话变量中是否没有坏处?我已经为站点上的每个访问者(无论是否登录)设置了会话id,因此我可以创建一个表,将登录尝试与该会话id关联起

我有一个需要用户名和密码的登录系统。我想在一定数量的登录尝试失败后显示验证码。实施这一点的正确方式是什么?我在这个网站上读过很多文章,一些解决方案建议将“失败尝试计数”添加到用户表中。但是,我需要将失败的尝试不绑定到某个用户-即,我希望显示验证码,无论输入的用户名是否存在于系统中。将其存储在会话变量中可以吗(我使用的是PHP)?如果是这样的话,仅仅根据需要将数据放入会话变量中是否没有坏处?我已经为站点上的每个访问者(无论是否登录)设置了会话id,因此我可以创建一个表,将登录尝试与该会话id关联起来。关于最佳/最安全的方法是什么,有什么想法吗?谢谢


更新:从目前为止的答案来看,会话ID似乎不是最好的主意,因为黑客可以简单地清除他/她的缓存(但这真的是一个问题,因为这不会降低暴力攻击的速度,使其变得无用吗?)。另一种选择是通过IP…但我对内联网或代理下的用户犹豫不决,因为失败的尝试将被共享…我真的想不出任何其他方法…你能吗?

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

使用会话ID的危险在于,编写暴力攻击的人每次尝试都可以清除cookie,从而给他一个新会话

请记住,自动暴力攻击可以在浏览器之外用脚本语言编写,该语言可以操纵为每个请求发送的cookie

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


更新:在连续的暴力尝试期间必须清除cookies不会减慢攻击速度,因为此过程将自动进行,并且几乎立即发生。在这些类型的攻击中,Cookie操作非常常见。修改cookie与清除浏览器缓存不同(通常需要一段时间,因为它需要删除一堆文件)。攻击者需要做的就是阻止发送cookie。

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

安装APC或memcache(d)或此处(memcache还需要安装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);
        }
    }
}

当然,这是一个非常粗略的例子。。。但是你得到了这个想法

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

对,但我认为验证码的想法首先是为了阻止自动暴力攻击。那么,每次尝试后关闭浏览器或清除缓存不会解决问题吗?你说的是存储每个用户的失败尝试-这是否意味着只有在有效的用户id存在时,失败尝试计数器才会增加已输入(如果用户id和密码都无效,则不会输入)?自动化良好的暴力攻击可以轻松摧毁WebClient对象,并为每次尝试创建一个新对象。关于第二部分,您可以在会话对象内实现第二个安全层,以防用户id无效,并解决该问题。然而,请注意,在每个用户的基础上存储黑客企图不仅可以禁止ip地址,还可以让您实际更改pw并将其发送到用户的电子邮件地址(我以前见过暴雪这样做)。