问题在于用户可访问性和攻击者模型之间的平衡。
第一个解决方案
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 CAPTCHA
用户:需要解决CAPTCHA(不太复杂)
攻击者:需要解决CAPTCHA(必须复杂)
很好的解决方案(并且被许多网站使用),但要小心我们的CAPTCHA。无论如何,有一个技巧(请参阅下一个解决方案)。
第五种解决方案
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 阻止,但必须记住其密码。
攻击者:很难进行有效的暴力攻击。
重要说明
是登录表单还是登录提交链接被阻止?阻止登录表单是无用的。
抵抗暴力破解首先是密码复杂性的问题,因此您需要严格的密码策略(特别是在分布式暴力破解的情况下)。
我没有提到用盐散列密码的事实,你已经这样做了吗?因为如果访问密码数据库比暴力破解更容易,攻击者将选择此解决方案(“链的强度取决于其最薄弱的环节”)。