Web 应用程序安全认证的最佳实践以避免暴力攻击

信息安全 Web应用程序 渗透测试 验证码
2021-08-18 08:07:55

我想介绍可能的攻击案例。我的应用程序已经有验证码和双因素身份验证,但我怎样才能在不惹恼用户的情况下避免微小的攻击呢?我想涵盖的可能情况是:

  1. 在基于 Session 的 3 次登录尝试失败后显示验证码,但问题是一些相关文章说它不应该基于 ASP.NET 会话,因为它可以以某种方式被清除。

  2. 在验证码之后显示两因素身份验证,但我是否也应该根据上一步的失败计数显示验证码?还是我应该从头算起?

  3. 此外,我正在考虑在一段时间内阻止用户的 IP,但这可能会影响使用同一 IP 工作的其他用户!如果黑客有定期更改 IP 的工具怎么办?

如果可能的话,您能否建议我提供参考资料,解决这些安全问题的最佳方法是什么?

3个回答

一种相对用户友好的减轻蛮力攻击的方法是延迟尝试之间的最短时间。当您的用户第一次输入错误的凭据时,您让他等待 1 秒钟,然后他才能重试。第二次,你让他等2秒。第三次,你让他等 4 秒。第 4 次,8 秒,以此类推。您还可以基于用于身份验证的用户名,而不是任何 IP 地址。如果在过去 5 分钟内没有尝试(或者如果用户成功通过身份验证),则重置计数器。

结果是,在密码中输入错误的用户最初几次不会受到影响,但任何暴力破解者都会很快达到暴力破解实际上不再可行的地步。


除了防止您的 Web 应用程序遭受暴力攻击之外,您还应该确保标准的密码保护做法,例如散列和加盐(最好使用 PBKDF2 或 bcrypt)、安全密码重置以及对用户名枚举的缓解。但我假设,既然你在这里发帖,你就已经知道了。

用户体验和安全性之间的一个很好的折衷方案是使用基于 IP 的验证码,该验证码会在从特定 IP 登录几次失败后触发,而不管用户名如何。

  • 这种方法不容易受到针对单个用户的 DoS 攻击,方法是暴力破解他的帐户,直到退避时间达到几个小时/天,并阻止帐户的合法所有者登录。

  • 被困在 NAT 后面的人数并不多,最好稍微降低他们使用验证码的体验,而不是让攻击者能够完全拒绝帐户并锁定其合法所有者。

  • 这取决于您的应用程序的用途以及会话生命周期的长短,但如果它类似于 Stack Exchange,那么人们通常不会经常登录和注销。

至于您对使用会话跟踪错误登录的担忧,您是对的,这是没有意义的,因为它适用于合法用户,但是攻击者甚至不会费心存储会话 cookie,这意味着每次尝试他都会得到一个新的没有验证码的会话和新登录尝试。

对于 IP 更改,是的,这有点问题,但 IP 仍然是攻击者的成本,最终他将用完他的僵尸网络中的代理和/或受感染的机器,他将不得不购买更多。如果 IP 在开放代理数据库(在 Google 上搜索)或 Tor 出口节点列表中,您还应该始终要求验证码;这样,攻击者将无法使用这些“免费”解决方案,而必须租用僵尸网络或一些尚未列入黑名单的“高级”代理。

我一直在做一些关于减轻暴力攻击的研究,并遇到了这篇文章。我最近实施了以下方法:

在 24 小时内:在对单个 IP 地址进行 20 次或更多失败的身份验证尝试时,我们需要对每次后续尝试进行验证码。在 100 次失败的尝试中,我们黑洞请求,但没有表明请求被黑洞,我们只是不断返回标准错误消息。

对我们来说,这是合理的,因为我们不担心大量用户从同一个 IP 登录,并且我们相信我们的阈值足够高,不会影响普通用户。在 100 次失败或用户名出现在多个 IP 地址时发送警报是微不足道的。

我们将所有内容都记录在数据库中。我们确实承认僵尸网络可以使用大量 IP,但是我们会记录 IP 无法通过身份验证的用户名。该表通常每天检查一次,因此我们可能存在识别针对单个用户的大规模暴力攻击。

我们最近还增强了密码要求,以增加字符长度和复杂性,并且不允许使用各种密码字典中的密码。我们的登录页面在 Google 中没有索引(不在 robots.txt 中,请使用元机器人标签,因为攻击者可以检查您的 robots.txt 中是否有有趣的页面)。最后,管理员帐户需要两因素身份验证。

尽管如此,我们还是接受了可能进行暴力破解的风险。