如何防止字典攻击?我想到了几种方案,但它们似乎都存在一些问题:
- 在X次失败的登录尝试后锁定用户。问题:容易被转化为拒绝服务攻击,在短时间内锁定很多用户。
- 针对用户名,每次登录失败时逐步增加响应时间。问题:字典攻击可能使用相同的密码但不同的用户名。
- 针对IP地址,每次登录失败时逐步增加响应时间。问题:易于通过欺骗IP地址来规避。
- 在会话中,每次登录失败时逐步增加响应时间。问题:易于通过创建新会话的字典攻击来规避。
如何防止字典攻击?我想到了几种方案,但它们似乎都存在一些问题:
安全性、可用性和易用性之间存在永恒的权衡,这意味着不存在完美的解决方案。
根据您的情况,一个不错的折衷方案是使用选项 #1 并添加验证码。在三次失败尝试后锁定账户,但如果正确解决了验证码,则允许后续的登录尝试。
我也建议使用第三个选项。虽然它对于拥有大量代理(或机器人网络)的攻击者不太好,但我仍然认为它是大多数网站的最佳答案。(Gmail面临与大多数网站不同的威胁,因此需要不同的响应。)
一个真实的例子:
我参与的一个大型在线游戏会跟踪过去5分钟内每个IP地址的失败登录尝试次数。一旦任何一个IP地址累积了5次错误的登录尝试(无论成功尝试的次数如何),该地址将被阻止45分钟。
为什么这有效
我坐下来计算了一下,高度智能的黑客可能会在大约100次尝试中破解一个帐户(可能更糟)。因此,最坏的情况下,攻击者每100分钟(每个IP地址)就会破解1个帐户。对于这个特定网站的威胁来说,这已经足够保护了。我们的帐户真的不值那么多钱。您需要确定(对于您的网站)需要多少保护。如果需要,您可以将时间窗口延长到30分钟,使其需要3倍的时间。
重要提示
不要在成功登录后重置计数(无论是用于解决方案3还是上述热图),否则攻击者将只尝试黑客入侵3个帐户,然后成功登录到他们已经控制的某个帐户(自己或已经被攻击的帐户),并且永远不会被限制。
首先,阻止用户选择常见密码。在您的数据库中添加“黑名单”,并检查新密码是否与其匹配。您可以使用许多密码或单词列表之一来填充它,例如这里:
http://securityoverride.org/infusions/pro_download_panel/download.php?did=66
其次,考虑临时锁定。如果您有一个“用户”表,请添加“LastLoginAttemptedOn”和“FailedLoginAttempts”列。每次用户尝试登录时更新这些值。当用户成功登录时,将FailedLoginAttempts重置为0。当FailedLoginAttempts达到4(或您喜欢的任何数字)时,不要让用户在LastLoginAttemptedOn之后的5分钟内尝试登录。在计时器重置之前不要更新此列,以防止4分钟后尝试重置计时器。当计时器重置时,将FailedLoginAttempts重置为0,以便他们有更多的重试机会。这取决于你所说的 "prevent" 是什么意思。
如果你不想让他们浪费你的带宽,限速、锁定等都是可行的选择。使用热表会有一些开销——你必须创建和维护逻辑、存储和管理 "热图" 等等。我也看到过一些基于 IP 地理位置的系统,如果用户尝试从 "遥远" 或 "未知" 的 IP 登录,会弹出验证码或更改其登录配置文件。
如果你只想大幅降低字典攻击的效果,可以在密码哈希中加盐。