在 Web 应用程序中,防止密码猜测攻击的一种方法是在一定次数的登录失败后锁定帐户。这可以在源 IP 地址和用户名上完成。
例如,下表显示了检测到重复尝试时会发生什么。系统设置为在 5 分钟窗口内 3 次登录失败后锁定帐户,持续 5 分钟。
IP Time Username Creds Correct? Message Given
203.0.113.1 10:00:00 foo@example.com N Bad username or password
203.0.113.1 10:00:01 foo@example.com N Bad username or password
203.0.113.1 10:00:02 bar@example.com N Bad username or password
203.0.113.2 10:00:03 foo@example.com N Bad username or password
203.0.113.1 10:00:04 foobar@example.com N Login locked from your location
203.0.113.2 10:00:05 foobar@example.com Y Welcome!
203.0.113.2 10:00:06 foo@example.com N Account locked
203.0.113.2 10:00:07 bar@example.com Y Welcome!
203.0.113.1 10:01:00 foobar@example.com Y Login locked from your location
203.0.113.1 10:05:03 foobar@example.com Y Welcome!
登录尝试仅在验证凭据时计入(该过程是在验证凭据之前首先检查锁定 - 如果锁定,则不验证凭据)。
从下面可以看出,恶意用户(在 IP 上203.0.113.3)可以通过故意反复猜错密码来锁定导致拒绝服务的帐户:
IP Time Username Creds Correct? Message Given
203.0.113.3 10:06:00 foo@example.com N Bad username or password
203.0.113.3 10:06:01 foo@example.com N Bad username or password
203.0.113.3 10:06:02 foo@example.com N Bad username or password
203.0.113.3 10:06:03 foo@example.com N Account locked
203.0.113.10 10:07:00 foo@example.com Y Account locked
203.0.113.10 10:07:04 foo@example.com Y Account locked
203.0.113.10 10:07:08 foo@example.com Y Account locked
203.0.113.10 10:07:15 foo@example.com Y Account locked
203.0.113.10 10:07:25 foo@example.com Y Account locked
...阻止真正的用户203.0.113.10登录。
另一种方法是人为地延迟 HTTP 响应。假设第一次登录失败延迟 1 秒,第二次延迟 2 秒,第三次延迟 4 秒,依此类推,总共 16 秒。如果他们的帐户受到攻击,用户在等待对登录请求的 HTTP 响应时会在浏览器中看到一个旋转的圆圈。
这有什么缺点吗?上面现在看起来如下所示(假设由于 bcrypt 迭代,默认延迟为 1 秒):
IP Req Time Resp Time Username Creds Correct? Message Given
203.0.113.3 10:06:00 10:06:01 foo@example.com N Bad username or password
203.0.113.3 10:06:01 10:06:03 foo@example.com N Bad username or password
203.0.113.3 10:06:03 10:06:08 foo@example.com N Bad username or password
203.0.113.3 10:06:08 10:06:17 foo@example.com N Bad username or password
203.0.113.10 10:06:18 10:06:35 foo@example.com Y Welcome!
请注意,人为延迟(当处于活动状态时)是跨线程的,这意味着攻击者无法以更快的速度从单个 IP 发送请求。来自不同 IP 的登录不会排队,尽管它仍然会经历因错误尝试用户名而造成的任何人为延迟。
正如你所看到的,用户并203.0.113.10没有被拒绝访问——他们只需要等待 17 秒才能完成登录,而攻击者必须延迟他们的攻击。因此,它可以有效地防止密码猜测攻击。
我的问题是这种方法的缺点是什么,为什么您不经常看到这种方法而不是可能导致拒绝用户服务的全面锁定?