我应该在网站或网络服务中实施不正确的密码延迟吗?

信息安全 验证 密码 蛮力
2021-08-11 05:13:56

使用此答案中表达的参数,用户输入错误密码与他/她实际学习密码不正确之间存在几秒钟的延迟。该安全解决方案在操作系统(这里是基本操作系统)和控制台命令等sudo中实现。

我应该在我的网站或 Web 服务中实施相同的机制吗?或者我可以很容易地假设,浏览器和服务器之间交换信息的典型延迟将足以阻止臃肿的暴力攻击(即使在本地系统上,Login在我的网站上按下按钮直到有关不正确的信息返回密码;这似乎足够长 AFAIK)。

关于这个问题有一个类似的问题但是,这两个答案(thisthis)都不能满足我的问题,甚至有点离题。我不是在询问每次登录失败后用户帐户的暂停或临时锁定(因此有关锁定攻击者阻止真实用户登录的论点已关闭)。我只是在谈论再次显示登录表单之间可能存在的延迟。

4个回答

我假设您使用失败延迟的目的是防止暴力攻击:如果攻击者试图猜测用户的密码,她首先会失败很多次;如果我们可以使这些失败花费更长的时间,那么它将使攻击更加困难,因此不太可能成功(在合理的时间范围内)。

然而。

这假设攻击者在登录尝试之间耐心等待。而且,众所周知,网络黑客是一个非常有礼貌和耐心的人。
也就是说,一些攻击者可能会选择不等待,而只是并行发送许多请求。如果登录尝试没有立即收到响应,攻击者可以将其解释为失败的尝试,终止该请求,然后继续下一个请求。

这种方案的一个额外好处是攻击者更容易在服务器上创建不合理的负载(只需发送大量失败的登录请求,每个登录请求都会占用一个线程几秒钟......),并且可能甚至成功对服务器进行 DoSing。

事实上,这个解决方案的主要问题是它不会阻止许多并行请求。如果攻击者正在尝试在线暴力攻击,她不会坐在键盘前一个接一个地输入许多密码,就像休·杰克曼一样快——如果是这样的话,你只会如果用户有一个无效的简单密码,则存在风险。
实际上,她将有一个脚本或自动化工具发送(几乎)服务器可以处理的尽可能多的请求,然后继续。风险不在于有人会在一分钟内尝试 30 个不同的密码,而是每分钟 1000 个密码,或 10,000 个。

防止这种情况的唯一方法是用户限制/帐户锁定/增量暂停 - 随便你怎么称呼它,这基本上与在给定时间范围内允许每个帐户进行 X 次登录尝试的想法相同。
因此,即使这没有减少到“一次登录尝试”,它确实足够接近。

部分问题在于,在等待延迟到期时保持连接打开会占用宝贵的资源,尤其是在某些流行的配置下,允许同时连接的数量非常少。

一个理想的解决方案是按如下方式构建您的系统:

  • 首先将逻辑设计到 UI 中。登录失败会立即返回失败状态,但在 UI 重置以允许再次登录尝试之前存在延迟。这不是为了强制执行规则,而是为了确保行为良好的用户永远不会看到错误消息。

  • 通过在“冷却”期间立即为任何登录尝试返回错误状态来强制执行后端逻辑。甚至不要检查密码是否正确,只需立即失败,同时消耗尽可能少的资源。

  • 要测试是否允许登录尝试,最好的解决方案是使用轻量级的东西,比如 memcached。例如,在使用给定用户名的尝试失败后,将冷却时间到期的时间存储在 memcached 中。然后,在尝试输入新密码时,检查 memcached 中的条目以查看冷却期是否已经结束。

  • 在每个 IP 的基础上执行相同的逻辑,而不仅仅是每个用户名。我不应该仅仅通过轮换用户名就能在一秒钟内猜出数千个密码。

  • 实施指数退避。这有点额外的功劳,但 1 秒内尝试 2 次并不是什么大问题,但 5 分钟内尝试 50 次是个大问题。这可能有点难以设计,但重复的故障应该会触发更长的复位时间。这可以像保持一个故障计数器(同样,在 memcached 中)并根据该计数器计算下一个冷却时间一样简单。但是,每个 IP 的逻辑必须有所不同,因为您不希望攻击者能够仅通过发送已知用户的凭据来重置他的计数器。

你希望你的服务器做尽可能少的工作,以避免你自己 DoSing。帐户锁定非常适合 DoSing 您的用户。

如果计数(用户名 U 的身份验证不成功)> 阈值,则需求已解决验证码

如果计数(密码 P 的身份验证不成功)> 阈值,则要求解决验证码

如果不喜欢 CAPTCHA,则要求工作证明

(让客户计算一个实大数的质因数)

传统的延迟将减轻基于 Web 浏览器的攻击,例如,如果有人使用 phantomjs 自动登录尝试,则正常延迟(在您的情况下为“超过一秒”)足以阻止任何人尝试暴力破解密码,它只是需要太长时间。

但是,大多数蛮力攻击不是在 Web 浏览器中运行,而是在脚本环境中运行,它们可以同时发出多个请求。

我实现它的方式是在登录失败后在服务器端故意延迟,加上一个节流机制(类似这样)和一个前端消息或微调器,通知用户正在检查凭据(没有人想要重新加载的空白页面或系统似乎挂了很长时间)