代码之家  ›  专栏  ›  技术社区  ›  Kevin Pang

防止对web应用程序的字典攻击

  •  17
  • Kevin Pang  · 技术社区  · 15 年前

    防止字典攻击的最佳方法是什么?我想了好几种实现方法,但它们似乎都有一些缺陷:

    1. 在X次登录尝试失败后锁定用户。问题:很容易演变成拒绝服务攻击,在短时间内锁定许多用户。
    2. 以增量方式增加每次登录用户名失败时的响应时间。问题:字典攻击可能使用相同的密码,但用户名不同。
    3. 从IP地址递增地增加每次失败登录尝试的响应时间。问题:通过欺骗IP地址很容易解决。
    4. 递增地增加会话中每次登录失败尝试的响应时间。问题:创建一个字典攻击,每次尝试都会触发一个新会话,这样很容易绕过。
    8 回复  |  直到 8 年前
        1
  •  21
  •   Noah Krasser    8 年前

    我很喜欢Gmail的反暴力系统。这是基于“热量”用户可以积累,用户过热后,他们会提示一个验证码。您可以使用sql数据库或 redis incr . 热被分配到一个IP地址。 完全不可能通过Internet“欺骗”TCP连接 因为 three-way-handshake 但是,代理服务器非常丰富,IP地址非常便宜。代理服务器通常用于发送垃圾邮件,您可以检查 blacklist 并自动提示他们输入验证码。

    对系统的每个错误操作都会更新热量表。例如,登录失败将累积35%的热量。一旦热量水平大于或等于100%,用户就被迫破解验证码。解决验证码将“冷却”该IP地址。heat表可以包含设置为更新时的当前时间的timestamp列。大约24小时后,热量可以恢复到0。

    reCaptcha 是你能使用的最安全的验证码。

        2
  •  3
  •   EMP    15 年前

    我一直是你选项3的粉丝——根据IP地址锁定或限制客户端。其他的选择都比你所说的要麻烦得多。

    欺骗一个IP地址是可能的,但它不能击败这个反措施。如果你的意思是技术意义上的“欺骗”——伪造TCP数据包头——那么这对攻击者没有多大好处,因为即使他们猜到了正确的密码,他们也不会收到告诉他们的响应。当然,他们仍然可以使用代理,但是代理的数量是有限的。即使攻击者可以使用1000个工作代理,并且每个IP允许10次尝试,即10000次尝试。如果您强制任何密码复杂性(例如需要字母数字密码),那么这将不足以猜测太多。

    光是这一点就足以阻止大多数脚本小子。如果你面对的是一个更坚定的攻击者,你可能必须实现某种类型的站点范围的监控,检测有许多尝试正在进行(所以可能有一个攻击正在进行),并以某种方式“锁定”,例如使用captchas。我不喜欢一直使用captchas——它们只是比它们的价值更烦人。

    最终,由用户选择安全密码(尽管您可以帮助他们)。如果他们选择了“password1”作为他们的密码,那么你所做的一切都无法阻止黑客入侵他们的帐户。

        3
  •  1
  •   Felix    15 年前

    也许你需要工具 CAPTCHA 在你的网络表单上。

        4
  •  1
  •   Thomas    15 年前

    安全性、可用性和可用性之间存在着永恒的权衡,这意味着没有完美的解决方案。

    根据您的情况,一个不错的折衷方案是使用带有验证码的选项1。尝试三次失败后锁定帐户,但如果正确解决了验证码,则允许随后的登录尝试。

        5
  •  1
  •   Eadwacer    15 年前

    我还建议使用选项3。虽然对于拥有大量代理(或bot网络)的攻击者来说,这不是一个好办法,但我仍然认为这是大多数站点的最佳解决方案。(Gmail有来自大多数网站的不同威胁,因此需要不同的响应。)

    一个真实的例子:
    我参与的一个大型在线游戏会记录过去5分钟内每个IP地址有多少次登录尝试失败。任何一个IP地址累积5次错误登录尝试(不管成功尝试的次数)的那一刻,该地址将被阻止45分钟。

    为什么这样做
    我坐下来决定,一个高度聪明的黑客将能够打破一个帐户与字典大约每100次尝试(可能更糟)。所以,更糟糕的情况是,攻击者每100分钟(每个IP地址)就会中断一个帐户。对于针对这个特定站点的威胁,这是足够的保护。我们的账户真的不值钱。你需要确定(为你的网站)你需要多少保护。如果你想把时间延长到30分钟,如果你需要的话,可以延长3倍。

    重要提示
    成功登录后重置计数(无论是针对解决方案3还是上述热图)。如果你这样做了,攻击者只会尝试黑3个帐户,然后成功登录到他们已经控制的某个帐户(他们的帐户或已经泄露的帐户),并且永远不会被阻止。

        6
  •  1
  •   Jim Carnicelli    13 年前

    首先,阻止用户选择常用密码。在数据库中添加一个“黑名单”,并检查新密码。您可以使用许多密码或单词列表中的一个来填充它,如下所示:

    http://securityoverride.org/infusions/pro_download_panel/download.php?did=66

    其次,考虑暂时关闭。如果有“user”表,请添加“lastloginattendon”和“failedloginattents”列。每次用户尝试登录时更新这些值。当用户成功登录时,reset failedloginattempts将返回到0。当FailedLoginAttents达到4(或您喜欢的任何内容)时,不要让用户尝试从LastLoginAttentedon登录5分钟(同样是您的首选项)。在实际允许他们尝试此列以防止4分钟后尝试重置计时器之前,不要更新此列。当计时器重置时,reset failedloginat将尝试为0,以便它们有更多的重试次数。

        7
  •  0
  •   0concern    15 年前

    这取决于你所说的“预防”是什么意思。

    如果你不想让他们浪费你的带宽,节流、锁定等是可行的选择。热量表有开销——你必须创建和维护逻辑,存储和管理“热量图”等。我还看到一些基于IP地理位置的系统,如果用户试图从“遥远”或“未知”IP登录,它们会抛出验证码或更改其登录配置文件。

    如果您只是想大量降低字典攻击的有效性,那么除了密码散列之外,还可以使用salt。

        8
  •  0
  •   Christian    15 年前

    如果您正在为安全性非常重要的应用程序编程,则可以禁止包含字典单词的密码。 你不必允许qwerty作为有效密码。