我有一个需要用户名和密码的登录系统。我想在一定数量的失败登录尝试后显示验证码。实现这个的正确方法是什么?我已经阅读了这个网站,一些解决方案建议在users表中添加'failed-attempts-count'。但是,我需要失败的尝试不与某个用户绑定 - 即我想要显示验证码,而不管输入的用户名是否存在于系统中。将它存储在会话变量中是否可以(我正在使用PHP)?如果是这样,将数据根据需要投入会话变量是否没有缺点?我已经为网站上的每个访问者提供了任何会话ID(无论是否已登录),因此我可以创建一个表,将登录尝试与此会话ID相关联...有关最佳/最安全方法的任何想法?感谢。
从目前为止的答案更新:,似乎会话ID不是最好的主意,因为黑客可以简单地清除他/她的缓存(但这真的是一个问题,因为这不会减慢蛮力攻击足以使它无用吗?)。另一种选择是通过IP ...但我对内网或代理下的用户犹豫不决,因为失败的尝试将被共享....我真的不能想到任何其他方法......你呢?
答案 0 :(得分:6)
使用会话ID的危险在于,撰写暴力攻击的人可以在每次尝试时清除他的cookie,从而为他提供新的会话。
请记住,可以使用浏览器之外的脚本语言编写自动暴力攻击,该语言可以操纵为每个请求发送的cookie。
另一种方法是创建一个包含用户源IP的表,并在那里添加计数器。这会给使用代理服务器的用户带来不便。但至少你会抓住那些试图反复猜测来自同一地点的密码的人。
更新:在连续暴力尝试期间必须清除cookie不会减慢攻击速度,因为此过程将自动化并几乎立即发生。这些类型的攻击中的Cookie操作非常常见。修改cookie与清除浏览器的缓存不同(这通常需要一段时间,因为它需要删除一堆文件)。攻击者需要做的就是阻止cookie的发送。
答案 1 :(得分:1)
如果黑客关闭浏览器并在每次尝试时重新打开它,会话方法将无法运行,因此存储失败尝试次数和最后一次尝试次数的表(这样您就可以检查是否说过一个小时,所以你可以重置计数器)每个用户是最安全的方式。
答案 2 :(得分:1)
您可以使用IP和时间记录所有失败的尝试。旧的失败尝试在一定时间后被删除,如果有更多失败的尝试,则给定的IP显示验证码。
答案 3 :(得分:1)
安装APC http://www.php.net/apc或memcache(d)http://www.php.net/memcache或此处http://www.php.net/memcached(memcache还需要安装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);
}
}
}
当然这是一个非常粗略的例子......但你明白了
答案 4 :(得分:0)
您可以获得的最准确信息是他们的IP地址。如果您希望会话cookie准确无误,请不要使用会话cookie,因为用户可能只是忽略您的会话cookie(即使用curl)。但是,如果您担心共享的ips,您可以尝试包含其他信息,例如浏览器代理或使用ajax传回您无法获得的其他信息。但是,除IP地址之外的其他所有内容都可以伪造(即使这样,您也可以使用代理)。