最佳分布式暴力破解对策是什么?

158

首先,一些背景信息:众所周知,我正在为CodeIgniter实现一个身份验证+授权系统,到目前为止我算是成功了(可以这样说)。但是我遇到了一个非常棘手的问题(大多数身份验证库都没有完全处理过,但我坚持正确地处理它):如何智能地处理大规模、分布式、变量用户名的暴力攻击

我知道所有常规的技巧:

  1. 限制每个IP/主机的失败尝试次数并拒绝攻击者访问(例如Fail2Ban) - 这已经不再起作用了因为僵尸网络变得更加聪明
  2. 结合上述方法使用已知的“坏”IP/主机的黑名单(例如DenyHosts)- 这依赖于僵尸网络对第一种方法的反应,他们越来越不会这样做
  3. IP/主机白名单与传统的身份验证结合使用(遗憾的是对于动态IP用户和大多数网站上的高换手率它毫无用处)
  4. 在一定的N分钟/小时内设置一个站点范围的限制,并在此之后将所有登录尝试进行节流(暂停)一定数量的分钟/小时(这会使DoS攻击变得更加容易)
  5. 强制要求所有用户使用数字签名(公钥证书)或RSA硬件令牌,并且不提供登录/密码选项(毫无疑问是一个坚如磐石的解决方案,但只适用于关闭、专用的服务)
  6. 实施超强密码方案(例如>25个无意义字符与符号 - 再次,对于普通用户来说太不实用了)
  • 最后,CAPTCHA(虽然在大多数情况下有效,但对用户很烦人,而且几乎毫无用处来对抗一个有决心、有资源的攻击者
  • 这些只是理论上可行的想法。还有很多垃圾想法可以轻松地打开网站(例如略微DoS攻击)。我想要的是更好的东西。所谓更好就是:

    • 它必须安全(+),不会引入新漏洞,以防止稍微狡猾的机器人持续潜伏。

    • 它必须自动化。如果需要人工操作员来验证每个登录或监视可疑活动,则在实际应用环境中无法工作。

    • 它必须适用于主流web应用程序(即高承载量、高流量和可以由非程序员执行的开放注册)。

    • 不能妨碍用户体验,以至于普通用户会感到恼怒或沮丧(并可能放弃该网站)。

    • 不能涉及小猫,除非它们是真的很安全的小猫。

    (+) 通过“安全”,我指的是至少与偏执用户保持密码机密性的能力一样安全。

    所以 - 让我们听听吧!你会如何做?你是否知道我没有提到的最佳实践(哦,请说你有)?我承认我有自己的想法(结合第3和第4个想法),但在让真正的专家发言之前,我会尴尬的;-)

    16个回答

    71
    将原帖中方法3和4结合为一种“模糊”或动态白名单,然后 - 这是关键 - 不要阻止非白名单IP,而是将它们限制到极致。请注意,此措施旨在挫败这种特定类型的攻击。实际上,它会与其他最佳实践方法相结合使用:固定用户名节流、按IP地址节流、代码强制执行强密码策略、无节流cookie登录、保存所有密码等价物之前进行哈希处理、永不使用安全问题等。

    对攻击场景的假设

    如果攻击者针对可变用户名,则我们的用户名节流不起作用。如果攻击者使用僵尸网络或访问大量IP范围,则我们的IP节流也无能为力。如果攻击者已经预先获取了我们的用户列表(通常可以在开放注册的网页服务上实现),我们无法根据“未找到用户”的错误数检测到正在进行的攻击。如果我们强制执行系统范围的(所有用户名、所有IP)节流,则任何此类攻击将使我们的整个站点在攻击期间加上节流时期被拒绝服务(DoS)。

    所以我们需要做些其他的事情。

    防御措施的第一部分:白名单

    我们可以相当确信的是,攻击者无法检测并动态欺骗我们数千个用户的IP地址(+)。这使得白名单成为可能。换句话说:对于每个用户,我们存储该用户最近登录的IP地址列表(经过哈希处理)。

    因此,我们的白名单方案将作为一个锁定的“前门”运行,只有连接到其已知的“好”IP之一的用户才能登录。对这个“前门”的暴力攻击几乎是不可能的(+)。

    (+) 除非攻击者“拥有”服务器、所有用户的计算机或连接本身--在这些情况下,我们不再面临“认证”问题,而是面临一个真正的规模如同特许经营的拔插FUBAR情况

    防御措施的第二部分:未识别IP的系统范围节流

    为了使白名单对开放注册的网络服务起作用,其中用户经常更换计算机和/或从动态IP地址连接,我们需要为从未被批准的IP连接的用户保持一个“猫门”开放。关键是设计这个门,以便僵尸网络被卡住,而合法用户受到的骚扰尽可能少

    在我的方案中,这是通过设置在3小时内未经批准的IP连接的极其严格的最大失败登录尝试次数(根据服务类型,使用较短或较长的时间段可能更明智),并将该限制应用于所有用户帐户的方法实现的。

    即使是缓慢(1-2分钟之间的尝试)的暴力破解也会被这种方法迅速有效地检测和挫败。当然,一个真正缓慢的暴力攻击仍然可能不被注意,但过慢的速度将打败暴力攻击的本质目的。
    我希望通过这种限制机制实现的目标是,如果达到最大限制,我们的“猫门”会关闭一段时间,但是我们的前门仍然对通过常规方式连接的合法用户开放:
    - 通过从他们认可的IP之一连接, - 或者使用持久性登录cookie(从任何地方)
    在攻击期间受影响的唯一合法用户是没有持久性登录cookie的用户,他们正在从未知位置或动态IP登录。 这些用户将无法登录,直到限制消失为止(如果攻击者继续运行他的僵尸网络,则可能需要很长时间才能消失)。
    为了让这个小子集的用户通过已被封闭的猫门,即使bot仍在努力攻击它,我会使用带有CAPTCHA的备份登录表单。这样,在您显示“抱歉,但是您目前无法从此IP地址登录”的消息时,请包含一个链接,上面写着“安全备份登录 - 仅限人类(bots:不要说谎”。开个玩笑,当他们点击那个链接时,请给他们一个reCAPTCHA认证的登录表单,该表单可以绕过全站点缓慢限制。这样,如果他们是人类,并且知道正确的登录+密码(并且能够读取CAPTCHA),即使他们正在连接到未知主机并且没有使用自动登录cookie,他们也永远不会被拒绝服务。
    哦,只是为了澄清:由于我认为CAPTCHA通常是邪恶的,因此“备份”登录选项只会在限制活动时出现。
    毫无疑问,像那样持续的攻击仍然构成一种DoS攻击形式,但使用上述系统只会影响我怀疑只有极小一部分用户,即不使用“记住我” cookie并且恰好在攻击发生时登录并且没有从任何常用IP登录的人们以及不能阅读CAPTCHA的人们。 只有那些能够满足所有这些标准的人,特别是bot和非常不幸的残障人士,在bot攻击期间将被拒之门外。

    编辑:实际上,我想到了一个方法,即使是验证码困难的用户也可以在“封锁”期间通过:与备用验证码登录相比或作为其补充,向用户提供将单次使用、特定于用户的封锁代码发送到他的电子邮件的选项,然后可以使用该代码绕过限制。这肯定超出了我的“烦恼”阈值,但由于它仅用作少数用户的最后手段,并且因为它仍然优于被锁定在您的账户之外,所以这是可以接受的。

    (还要注意:如果攻击不像我在这里描述的那样复杂,则没有任何全站后果。如果攻击只来自几个IP地址或仅针对几个用户名,则它将很早就被挫败。)


    因此,这就是我将在我的认证库中实施的反制措施,一旦我确信它是有效的,并且我没有漏掉更简单的解决方案。事实是,在安全方面有很多微妙的做错事情的方式,我并不排除会做出错误的假设或无望的缺陷逻辑。因此,请提供任何和所有的反馈、批评和改进,细微之处等都将不胜感激。


    1
    也许您可以为每个用户生成一个“特殊”的密码,以便在锁定模式下使用(如果他们从新的 IP 地址连接等),这个特殊密码足够复杂,不可能被暴力破解? - Douglas Leeder
    2
    然而,确实可行的一种方法是为这些用户提供一个“发送锁定代码”的链接,让他们收到一封电子邮件,其中包含一个单次使用、用户特定的令牌,可以让他们绕过限制登录。 - Jens Roland
    1
    @OrestisP:你没有理解分布式攻击的重点——每个IP的无效尝试次数很少,因此每个IP的阻止都不起作用。此外,问题明确描述了自动化暴力攻击,因此1)攻击者不是人类,而是僵尸机器的botnet(无法使用验证码登录);2)攻击的暴力性质需要非常高数量的登录尝试才能确保成功,这意味着将验证码解决外包给某个血汗工厂并不可行(尽管如果攻击者资金充足且足够坚定,则有可能)。 - Jens Roland
    1
    @OrestisP:不,这个数字会更高,取决于您网站的基线流量。全站限制不是按IP进行的,而是全局性的。因此,如果该站点从任何IP地址接收到太多失败的登录尝试,针对任何数量的用户名(例如user:homer;pass:incorrect和user:lisa;pass:incorrect和user:bart;pass:incorrect),都在预定时间内,限制将生效。 - Jens Roland
    1
    澄清一下,您的帖子中写道“未经批准的IP尝试登录失败”,但是您的评论中写道“来自任何IP的登录失败” 。我可以理解您的评论是一个打字错误吗? - Curt
    显示剩余10条评论

    17

    几个简单的步骤:

    黑名单某些常见的用户名,并将它们用作诱饵。例如管理员、访客等等... 不要让任何人使用这些名称创建帐户,这样如果有人尝试登录这些帐户,您就知道他们在做一些不应该做的事情。

    确保在站点上拥有真正权力的任何人都有一个安全的密码。要求管理员/版主使用包含字母、数字和符号的混合字符更长的密码。对于普通用户,拒绝过于简单的密码,并提供解释。

    最简单的事情之一是告诉人们,当有人尝试登录到他们的账户时,并给他们一个报告此事件的链接(如果这不是他们本人操作)。例如他们登录时显示“有人在周三凌晨4:20尝试登录您的账户,请点击此处如果这不是您本人的操作。” 这让您可以保持对攻击的统计。如果发现欺诈访问的突然增加,您可以加强监控和安全措施。


    好的想法。我肯定打算实现一种自动密码策略,根据用户的权限级别动态变化。蜜罐的想法可能对某些类型的攻击有效,但如果攻击是分布式的,阻止掉落进去的IP地址将不会有效。 - Jens Roland
    关于“上次尝试登录时间”,这对于高级用户来说是一个好策略(我敢打赌这就是SO这样做的原因),但它有两个弱点:(a)它没有解决入侵问题,只是报告可能已经发生了,(b)大多数用户只是不记得或不在意。 - Jens Roland
    1
    是的,蜜罐和用户报告更多地涉及信息收集。它们可以提供一些有价值的指标,让您知道何时发生缓慢的暴力攻击。 - patros
    2
    对于蜜罐,将任何不存在的用户名视为可疑是否比仅使用已知坏用户名的固定列表更好?您希望避免锁定多次输入密码但未注意到用户名拼写错误的用户,但我仍然认为它可能有价值。您甚至可以通过构建一个包含有效用户名、名字、姓氏、电子邮件名称等变体的大型布隆过滤器或类似数据结构来避免一些“误报”。随着用户的增加,这些变体也会不断增加。 - R.. GitHub STOP HELPING ICE

    11

    如果我正确理解了暴力攻击的作法,那么一个或多个用户名会不断尝试。

    这里有两个建议,我认为还没有看到:

    • 我一直认为标准做法是,在每个错误的登录后都有短暂的延迟(一秒左右)。这可以防止暴力攻击,但我不知道一秒的延迟能让字典攻击如何受挫。(10000个单词的字典== 10000秒==约3小时。嗯,不够好。)
    • 与其全站放慢速度,为什么不进行用户名流量控制呢?每次尝试失败后,流量控制就越来越严格 (最多到一个限制,我猜是为了让真正的用户仍然能够登录)

    编辑: 针对用户名流控的评论:这是基于用户名的特定流控,而不考虑攻击源。

    如果对用户名进行流控,那么即使是协调攻击用户名 (多个IP,单个IP猜测,相同的用户名),也会被捕获。即使攻击者在计时器超时期间可以尝试另一个用户/密码,但是单个用户名仍受到流量控制的保护。

    从攻击者的角度来看,在计时器超时期间,您可以首次猜测100个密码,并快速发现每个帐户一个错误的密码。对于相同时间段,你可能只能做出50次尝试。

    从用户帐户的角度来看,即使猜测来自多个源,破解密码所需的平均次数仍然相同。

    对于攻击者来说,最好的情况是破解100个帐户与破解1个帐户的努力程度相同,但由于不是在全站范围内进行流量控制,因此可以很快加强流量控制。

    额外的细化:

    • 检测正在猜测多个帐户的IP - 408请求超时
    • 检测正在尝试猜测同一帐户的IP - 在大量(例如100)次尝试后会出现408请求超时。

    UI想法(在此上下文中可能不适用),这也可以改善上述问题:

    • 如果您掌控密码设置,则向用户展示他们的密码强度,可以鼓励他们选择更好的密码。
    • 如果您掌控登录页面,在尝试单个用户名的少量(比如10次)猜测后,提供验证码。

    一个用户名限制加上IP限制可以很好地防范固定用户名或固定IP攻击,并且它们确实使传统的字典攻击变得不可行。但是,如果攻击者不断更改用户名,他将会在不触发用户名限制的情况下溜过去。这就是我想要对抗的。 - Jens Roland
    3
    感谢你编辑了一下,jamesh。现在我们可以开始交流了。我喜欢这个408的想法。但是,即使采用了严格的用户名限制,一个僵尸网络攻击多个用户仍然会起作用。而且,检查前5000个密码是否与一个用户匹配,比检查5000个用户中的前1个密码要不容易成功。 - Jens Roland
    1
    没有什么像生日悖论一样的东西。在一个庞大的群体中,许多人会使用不安全的密码,而很可能会有一个人使用任何一个流行的密码。还会有相当数量的人和我一样,不会被这样的攻击所捕获。 - David Thornley
    3
    实际上,我可能需要重新检查我之前陈述中的数学计算。一旦你排除了最常见的N个密码,用户使用密码#(N+1)的概率可能会增加到足以使差异平衡。尽管曲线可能陡峭到不会出现这种情况。 - Jens Roland

    10

    认证有三个要素:

    1. 用户知道某些内容(如密码)
    2. 用户拥有某些物品(如令牌)
    3. 用户某些东西(如视网膜扫描)

    通常,网站只强制执行策略#1。即使大多数银行也只执行策略1。它们反而依赖于一种“知道其他内容”的双因素身份验证方法。(例如:用户知道他们的密码和母亲的婚姻姓氏。)如果您有能力,添加第二个身份验证因素不太困难。

    如果您能生成大约256个随机字符,则可以将其构建成一个16x16的表格,然后要求用户给出表格中A-14单元格的值。当用户注册或更改密码时,请给他们这个表格并告诉他们打印并保存它。

    这种方法的困难之处在于,当用户忘记密码时,您不能只提供标准的“回答问题并设置新密码”,因为这也容易受到暴力攻击。此外,您不能重置密码并向他们发送新密码,因为他们的电子邮件可能也已经被攻击了。(参见:Makeuseof.com及其被盗的域名。)

    另一个想法(涉及小猫),是BOA所称的SiteKey(我相信他们已经注册了商标)。简而言之,您让用户在注册时上传一张图片,并在他们尝试登录时要求他们从8个或15个(或更多)随机图片中选择自己的图片。因此,如果用户上传自己小猫的图片,理论上只有他们知道所有其他小猫(或花朵或其他东西)中哪张图片是他们自己的。这种方法唯一的真正漏洞是中间人攻击。

    还有一个想法(不过没有小猫),就是跟踪用户使用的系统IP地址,并要求他们在从之前未登录过的地址登录时进行额外的身份验证(例如验证码、选择一只小猫或从表中选择一个密钥)。此外,与Gmail类似,允许用户查看他们最近登录的位置。

    编辑,新想法:

    另一种验证登录尝试的方法是检查用户是否来自您的登录页面。您不能检查引用页,因为它们很容易被伪造。您需要在用户查看登录页面时在_SESSION变量中设置一个密钥,然后在他们提交登录信息时检查该密钥是否存在。如果机器人未从登录页面提交,则无法登录。您还可以通过将JavaScript介入到流程中(例如使用JavaScript设置cookie或在加载后向表单添加一些信息),或者将表单分成两个不同的提交(即,用户输入用户名并提交,然后在新页面上输入密码并再次提交)来方便此操作。

    在这种情况下,密钥是最重要的方面。生成键的常见方法是结合用户数据、IP和提交时间等几个因素。


    3
    嗯,昨晚我回家后想到了你提出的观点。我认为解决这个问题的方法是:当用户登录并输入正确的密码时,显示他们的头像和其他一些随机头像。当他们没有输入正确的密码时,显示一些其他随机头像。 - davethegr8
    1
    图片 + 1,它们可能包括自己的图像。此外,我还有一个想法,请参见帖子中的编辑。但是,这些想法有点困难/复杂。 - davethegr8
    我实际上想到了一个与“小猫”想法不同的点子:第一次登录时,从Flickr中显示一张随机图片,并要求用户通过单击来选择3-5个“有趣”的位置,并存储图像和坐标。在用户下一次登录时,显示图像加上另一张随机的Flickr图像。 - Jens Roland
    请要求用户在两张图像中点击3-5个“有趣”的点。如果用户选择与其先前登录时相同的(大致)坐标,则进行身份验证并存储新的图像+坐标。每次登录都使用新图像重复此过程。 - Jens Roland
    1
    “可能”会起作用,但我看到了几个问题。如果照片所有者删除了图像会发生什么?您如何确保返回的图像不会冒犯您的用户?用户如何记住他们单击的位置?(似乎很难忘记) - davethegr8
    显示剩余7条评论

    7
    我之前在 如何在PHP中限制用户登录尝试次数 中回答了一个非常相似的问题。我在这里重申提出的解决方案,因为我认为许多人会发现它信息量大且有用,可以看到一些实际的代码。请注意,由于现在使用的CAPTCHA破解算法越来越准确,使用CAPTCHA可能不是最好的解决方法:

    您不能仅通过将限制放置在单个IP或用户名上来防止DoS攻击。实际上,您甚至无法使用此方法防止快速登录尝试。

    为什么?因为攻击可以跨越多个IP和用户帐户,以绕过您的限制尝试。

    我已经在其他地方发布过,理想情况下,您应该跟踪整个站点上的所有失败的登录尝试,并将它们关联到时间戳,例如:

    CREATE TABLE failed_logins(
        id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        username VARCHAR(16) NOT NULL,
        ip_address INT(11) UNSIGNED NOT NULL,
        attempted DATETIME NOT NULL
    ) engine=InnoDB charset=UTF8;
    

    根据一定时间内失败登录的总数,决定一些延迟。您应该基于从failed_logins表中提取的统计数据进行基础,因为它会随着用户数量以及能够回忆起(并输入)密码的用户数量的变化而变化。
    10 failed attempts = 1 second
    20 failed attempts = 2 seconds
    30 failed attempts = reCaptcha
    

    查询每次失败的登录尝试的表,以查找给定时间段内(例如15分钟)失败登录的次数:
    SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute);
    

    如果在给定时间内的尝试次数超过了您的限制,请强制执行节流或强制所有用户使用验证码(例如 reCaptcha),直到给定时间段内的失败尝试次数低于阈值为止。
    // array of throttling
    $throttle = array(10 => 1, 20 => 2, 30 => 'recaptcha');
    
    // assume query result of $sql is stored in $row
    $sql = 'SELECT MAX(attempted) AS attempted FROM failed_logins';
    $latest_attempt = (int) date('U', strtotime($row['attempted']));
    // get the number of failed attempts
    $sql = 'SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute)';
    // assume the number of failed attempts was stored in $failed_attempts
    krsort($throttle);
    foreach ($throttle as $attempts => $delay) {
        if ($failed_attempts > $attempts) {
            // we need to throttle based on delay
            if (is_numeric($delay)) {
                $remaining_delay = time() - $latest_attempt - $delay;
                // output remaining delay
                echo 'You must wait ' . $remaining_delay . ' seconds before your next login attempt';
            } else {
                // code to display recaptcha on login form goes here
            }
            break;
        }
    }
    

    在某个阈值处使用reCaptcha可以确保多方攻击被最小化,正常的站点用户在合法的登录失败尝试时不会遇到显着的延迟。我无法保证预防,因为已经扩展了CAPTCHA可以被破解。有替代方案,也许一个“命名这种动物”的变体可以作为替代品很好地运作。

    6
    我需要问一下,你是否对这个问题进行了成本效益分析?看起来你正在试图保护自己免受攻击者的攻击,攻击者有足够的网络存在感来猜测多个密码,每个IP地址可能发送3-5个请求(因为你已经排除了IP限速)。这种攻击大约会花费多少钱?它比你试图保护的账户价值更贵吗?有多少庞大的僵尸网络想要得到你所拥有的东西?
    答案可能是否定的,但如果是,我希望你能从某种安全专业人士那里获得帮助;编程技能(以及StackOverflow得分)与安全知识并没有强烈的相关性。

    您的意思是说,如果答案是“否”,即与账户相比,僵尸网络攻击的成本并不太高? - Jens Roland
    但无论如何,您提出了一个重要的观点。对于我自己的使用,我不指望任何僵尸网络操作者会在乎,但我将发布源代码供任何想要为其Web应用程序提供良好安全性的人使用,并且我无法知道其他人可能正在尝试保护什么或他们的敌人是谁。 - Jens Roland
    1
    我的简短回答是:我正在构建这个项目,因为99.9%的网站和应用程序都存在可怕的安全问题(即使在大公司如AOL、Twitter、Myspace也曾被攻击过),而且在大多数情况下是因为它们使用了劣质的身份验证库。 - Jens Roland
    @JensRoland,你写道你将发布源代码。那么怎样才能获取它呢? - Curt
    @Curt:恐怕我在写这篇文章后不久就换了工作,这个项目最终变成了虚无缥缈的东西。 - Jens Roland
    显示剩余2条评论

    5
    总结Jens的方案,可以用伪状态转换图/规则库表示如下:
    1. 用户+密码->进入
    2. 用户+!密码->拒绝
    3. 用户+已知IP(用户)->前门,//永不限制
    4. 用户+未知IP(用户)->猫门
    5. (#被拒绝>n)通过猫门(站点)->限制猫门(站点)//减缓机器人
    6. 猫门+限速+密码+验证码->进入//仍然欢迎人类
    7. 猫门+限速+密码+!验证码->拒绝//来自机器人的正确猜测
    观察结果如下:
    • 永远不要限制前门。埃尔博尼亚州警察局有你的电脑在你家里,但无法审问你。从你的电脑进行暴力攻击是可行的方法。
    • 如果提供“忘记密码?”链接,则您的电子邮件帐户成为攻击面的一部分。
    这些观察结果涵盖了与您试图对抗的不同类型的攻击。

    绝对的,电子邮件帐户是攻击面的一部分。我对我的策略提供的安全性有一组上限假设,而最低限度是用户自己的电子邮件安全性。如果攻击者入侵了用户的电子邮件,那么所有的赌注都是无效的。 - Jens Roland
    另外,我认为您的状态转换图需要一些细节:#3和#4应该包括密码;#1和#2应该包括已知IP(用户),因为登录始终具有已知或未知的IP;而#6是“尽管限制而进入”。 - Jens Roland

    4

    看起来您正在试图防御缓慢分布式暴力破解攻击。对此,您能做的并不多。我们正在使用PKI和无密码登录。这有所帮助,但如果您的客户偶尔更换工作站,那么这种方式就不是很适用了。


    实际上,暴力破解速度也很快。我本来希望对固定用户的暴力破解宽容一些(仅限制在20秒内),但在一个有50k用户的网站上,这将使得可变用户的快速暴力破解成为可能(假设需要20秒以上才能循环遍历所有用户)。正如他们所说,那将是糟糕的。 - Jens Roland
    快速暴力攻击来自单个主机的情况下,使用iptables或您所使用的任何防火墙。 - raupach
    我指的是分布式快速暴力破解。这种情况很少见,但潜在的危害非常大。 - Jens Roland

    3
    免责声明:我在一家双因素认证公司工作,但这里不是为了推销。以下是一些观察结果。
    Cookie 可以被 XSS 和浏览器漏洞窃取。用户常常更换浏览器或清除他们的 Cookie。
    源 IP 地址同时具有动态可变性和欺骗性。
    验证码很有用,但不能验证特定的人类。
    多种方法可以成功结合,但需要好的品味。
    密码复杂度很好,任何基于密码的东西都极其依赖密码具有足够的熵。在我看来,写在安全的物理位置上的强密码比存在内存中的弱密码更好。人们知道如何评估纸质文档的安全性,而不知道如何计算将宠物名用作三个网站的密码时所具有的有效熵。考虑给用户能力打印出一个大或小的页面,充满一次性使用的密码。
    像“你的高中吉祥物是什么”这样的安全问题主要是“你所知道的”另一种糟糕形式,其中大部分容易猜测或公开。
    正如您所指出的,减缓登录失败尝试是防止暴力攻击和帐户 DoS 的权衡。积极的锁定策略可能反映出对密码熵的信心不足。
    我个人认为,在网站上强制执行密码到期的好处并不大。攻击者一旦获得您的密码,就可以像您一样轻松地更改密码并遵守该策略。也许一个好处是用户可能会更快地注意到攻击者更改了帐户密码。更好的做法是在攻击者获得访问权限之前以某种方式通知用户。像“自上次登录以来失败了 N 次尝试”这样的消息在这方面很有用。
    最佳安全性来自于第二因素的身份验证,其相对于第一因素是超出带宽的。正如您所说,“你拥有的东西”的硬件令牌非常好,但许多(而不是全部)与其分发相关的真实管理员开销。我不知道有哪些适用于网站的生物识别“你是谁”的解决方案。一些双因素解决方案与 openid 提供商一起使用,一些具有 PHP/Perl/Python SDK。

    所有的观点都很好 - 我完全赞同。关于Cookie不安全的观点非常有道理,但是如果没有物理令牌或分布在安全线路上的一次性密码的第二因素,您确实无法防止弱点终端。如果用户的计算机/浏览器受到攻击,那么他的登录信息也会受到威胁。 - Jens Roland

    1
    1. 在输入正常密码之前,要求输入一次性密码怎么样?这将使得在攻击者有机会猜测主密码之前,很明显地发现有人正在攻击。

    2. 保持全局登录失败计数/速率 - 这是攻击的指标 - 在攻击期间,对登录失败更加严格,例如更快地禁止IP。


    1. 如何在不安全、未认证的线路上实现一次性密码?换句话说,用户何时设置这些一次性密码?
    2. 是的,这就是我列表中第4点的要点,即整个站点对失败尝试的限制。缺点是它会打开DoS攻击的机会。
    - Jens Roland

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接