暴力预防:何时何地?

信息安全 验证 蛮力
2021-08-21 09:23:22

我设计了一个“安全”的登录系统。让我们专注于暴力预防。在我的 Android 客户端中,我有一个计数器,用于计算用户尝试使用错误凭据登录的次数。当它达到 3 次尝试失败时,我禁用登录按钮和密码字段,强制用户重新启动应用程序,从而阻止暴力攻击。这是正确的做法吗?

或者我应该在服务器中放置一个计数器?但是在服务器中它可能导致 DoS,如果我同时收到很多暴力尝试,对吗?

这个想法是停止无限数量的输入,所以我认为这可以在应用程序端完成,在我的例子中是在 Android 客户端。

我愿意接受建议。

4个回答

客户端措施只是部分(并且主要是装饰性的)解决方案,这只能限制非严肃的尝试。任何严重的尝试都会因为检测到登录 URL/API 而直接攻击您的服务器,或者将通过拦截代理运行您的客户端以捕获创建蛮力运行所需的详细信息。

强大的防御通常要求您假设攻击者知道系统的所有信息,除了密钥Kerckhoff 原则),因此您应该从该位置开始。

缓解措施包括:

  • 使攻击者难以/不可能确定有效的用户名、无效密码或锁定帐户(基本上是最少的反馈,即没有“无效用户名”或“密码太长”消息,但如果这对用户支持)。正如My1在评论中指出的那样,开放注册可能是这里的一个弱点。
  • 很难确定除了成功或失败之外的任何事情,失败的登录应该与成功的登录时间相同 - 这通常意味着人为地延长两者(200ms是一个起点)
  • 使用 nonce 或一些基于时间或会话的令牌使登录 API 多步骤,以使自动攻击复杂化,并防止分布式攻击;或添加一些客户端工作证明(客户端密码散列是一种选择,但需要仔细考虑
  • 确保密码空间足够大,鼓励(并支持!)使用密码管理器
  • 使用帐户锁定和源 IP 锁定,锁定时间呈指数增长(例如,每次失败时将锁定时间加倍,这应该避免惹恼多次输入错误密码的用户)。如评论中所述,这是 DOS 的机会,因此请仔细考虑权衡
  • 实现自适应速率控制和恶意活动检测(这通常比任何其他解决方案都更难,因为它需要服务器端的额外状态和逻辑)
  • 考虑添加可以根据需要启用的“受到攻击”操作模式,理想情况下这将对用户的影响最小

来自CAPEC-112蛮力

这种攻击的关键因素是攻击者快速探索可能的秘密空间的能力。虽然防御者无法控制攻击者可用的资源,但他们可以控制秘密空间的大小。防御者必须依靠确保这样做所需的时间和资源将超过信息的价值。

另请参阅CAPEC-49密码暴力破解

防止暴力攻击的惯用方法是在服务器上增加一点延迟。

正如用户 immibis在评论中指出的那样,攻击者不需要使用您的应用程序来执行 DoS 或 DDoS。攻击者所需要的只是端点,然后他们可以淹没它。他们可以通过对 .apk 文件进行逆向工程或仅通过监控传出流量来找到端点。

所以防御必须在服务器端。通过在每次失败的登录尝试后添加一点延迟(例如 1 秒),攻击者尝试数百万个可能的用户名/密码组合变得不切实际。

如果您希望保护您的服务器免受一般 DDoS 攻击,您需要一个强大的服务器场,或者使用像 CloudFlare 这样的服务。

一个重要方面是设备上是否存储有任何类型的密钥材料可用于验证设备,或者用户是否可以简单地使用全新的设备,下载应用程序并登录。

如果设备上有这样的密钥材料,则服务器可以对每个设备应用速率限制。服务器端应用速率限制的其他方法(例如每个 IP 或每个用户名的速率限制)是潜在的 DoS 攻击向量。无论速率限制是通过让服务器执行 CPU 繁重的计算作为密码验证的一部分还是通过临时锁定来实现的,都是如此。

当您同时控制客户端和服务器代码时,您可以设计一个协议,其中 CPU 的主要验证部分在客户端完成,但服务器仍然执行加盐哈希以确保您仍然拥有服务器端验证的好处。显然,如果您从头开始实施这样的事情,则存在由设计或实施缺陷引入的漏洞风险。

做 CPU 密集型部分客户端的好处是它主要消除了 DoS 攻击向量。做 CPU 密集部分客户端的一个缺点是客户端可能在 CPU 资源方面受到限制。

结合上述方法是可能的。在第一次登录时,您可以让客户端进行几秒钟的散列,例如通过向客户端发送盐并让它进行多轮散列,最后服务器使用不同的盐进行最后一轮散列。如果密码被接受,设备将发送一个令牌,该令牌将允许客户端在未来使用更便宜的二级哈希对同一帐户进行身份验证。在令牌过期并且客户端返回到较慢的哈希之前,服务器可以强制限制允许使用令牌的失败登录尝试次数。

我必须再次警告说,有很多方法可以在这样的设计中引入安全漏洞,因此您必须采取这种方式来应对暴力攻击的风险。

可以将设备缓送和工作证明结合起来:

如果每个设备都必须使用自签名密钥(约 4096 位)作为设备标识进行连接,并且用于速率限制:

任何一个

  • 每个设备花费过多的时间来生成新的密钥;从而延迟密码尝试
  • 许多登录使用相同的客户端密钥;保证是单个恶意设备,因此可以在没有服务 DOS 风险的情况下被阻止。
  • 发生了一些僵尸网络风格的密钥与登录共享;受限于可用于生成新密钥的设备的能力 --- 您的服务的目标价值与您可以让用户等待第一次登录/证书密钥生成多长时间?

或者只是让它成为别人的问题 - 使用公共的 2 因素身份验证系统。