我正在尝试编写一个脚本,以防止在我正在构建的网站中进行暴力登录尝试。逻辑是这样的:
sleep(10)
,然后向用户报告登录失败。向同事解释这个问题时,有人问我,如果黑客在一秒内发送了1000个请求,这会有什么帮助。前5个会立即返回,然后剩下的995只需要10秒吗?
我有一种潜在的怀疑,即我不完全理解HTTP是如何工作的 - 甚至可能是上述情况,还是服务器将从一个客户端处理的并发请求数量有限制?
更好的解决方案是增加睡眠时间吗?
sleep($numRequestsInLast5Minutes - 5)
所以前5个会很快,然后每个后续的都会增加睡眠。
答案 0 :(得分:15)
问题在于用户可访问性和攻击者模型之间的平衡。
If not password correct for a certain number of time:
block the user
send a reset link to the user
用户:可能被阻止,他们不想重置
攻击者:通过尝试向所有用户进行身份验证来阻止所有用户(特别是如果所有登录都是公开的)
If not password correct:
sleep(amount_of_time)
问题是:'amount_of_time'的价值是多少?
用户:对于每个错误等待'amount_of_time'可能会很烦人 攻击者:继续尝试,使用较低的测试/秒
If not password correct:
sleep(amount_of_time)
amount_of_time = amount_of_time * 2
用户:对于少数密码错误不那么讨厌 攻击者:通过发送大量错误密码阻止用户连接
If not password correct for a certain number of time:
submit a catchpa
用户:需要解析CAPTCHA(不太复杂)
攻击者:需要解析CAPTCHA(必须是复杂的)
良好的解决方案(并被许多网站使用)但be careful to our CAPTCHA. implementation。无论如何,有一个技巧(见下一个解决方案)。
If not password correct for a certain number of time:
block the ip
(eventually) send a reset link
用户:用户可能会因为无法正确记住密码而被阻止 攻击者:尝试使用不同用户的相同密码,因为阻止是基于用户登录的次数。
If several login attempts failed whatever is the user by an IP :
print a CAPTCHA for this IP
用户:用户无法阻止IP,但必须记住密码 攻击者:难以进行有效的暴力攻击。
登录表单或登录提交链接是否被阻止?阻止登录表单是没用的。
对蛮力的抵抗首先是密码复杂性的问题,因此您需要严格的密码策略(特别是在分布式暴力破解的情况下)。
我没有提到用盐哈希你的密码的事实,你已经这样做了吗?因为如果访问密码数据库比强制攻击更容易,攻击者将选择此解决方案(“A链只有最薄弱的链接”)。
答案 1 :(得分:13)
我建议如果用户尝试失败,例如超过五次和五分钟,则立即开始为该IP地址返回503 Service Unavailable
。当登录失败时,您可以使用memcache获取IP的当前错误尝试,然后增加金额,并将其保存到memcache,并在5分钟到期。
您不希望在PHP代码中放置sleep
,因为这将允许单个用户创建大量与Web服务器的连接,并可能导致其他用户失望。
由于用户尚未登录,因此您没有会话cookie,如果用户试图强行进入帐户,他们可能根本不会提供cookie。
答案 2 :(得分:4)
我用过这样的东西......
检查用户名和密码
1.1如果不匹配,则记录该组合的最后登录失败时间和登录失败次数。
1.2每次失败都会在能够登录failCount * 30秒之间等待,直到达到最大值(例如10分钟)。
我已经开发了这个,但还没有将它发布到野外,所以任何反馈都会受到赞赏。
答案 3 :(得分:2)
我创建了一个在PHP中处理暴力攻击保护的类。
https://github.com/ejfrancis/BruteForceBlocker
它会在db表中记录站点范围内的所有失败登录,如果在过去10分钟(或您选择的任何时间范围)中失败的登录次数超过设定限制,则会强制执行时间延迟和/或再次登录之前的验证码要求。
示例:
//构建油门设置数组。 (#recent failed logins => response)。
$ throttle_settings = [
50 => 2, //delay in seconds 150 => 4, //delay in seconds 300 => 'captcha' //captcha
];
$ BFBresponse = BruteForceBlocker :: getLoginStatus($ throttle_settings);
// $ throttle_settings是一个可选参数。如果没有包含,将使用BruteForceBlocker.php中的默认设置数组
切换($ BFBresponse ['status']){
case 'safe': //safe to login break; case 'error': //error occured. get message $error_message = $BFBresponse['message']; break; case 'delay': //time delay required before next login $remaining_delay_in_seconds = $BFBresponse['message']; break; case 'captcha': //captcha required break;
}
答案 4 :(得分:1)
我不确定最佳做法是什么,但在处理DoS攻击时,更好的策略是实际从您的服务器转移远离的流量。设置超时实际上并没有帮助,因为您仍在处理请求并运行PHP。
您是否考虑过设置另一个运行更简单的登录页面的Web服务器?当用户尝试太多次(例如,数千次)时,发送消息以配置路由器并将该用户重定向到第二个Web服务器。
就像网站被slashdot效应所击中一样,其中许多只是将流量重定向,直到流量减少。