【问题标题】:Preventing brute force attacks where many users share an IP address防止许多用户共享一个 IP 地址的暴力攻击
【发布时间】:2014-07-26 02:15:43
【问题描述】:

我和我的团队正在用 PHP5.5 编写一个 Web 应用程序,其中的数据库(除其他外)具有用于用户身份验证的典型用户名和密码查找。

我们正在寻找防止超过相对数量(例如 8 次)错误登录的方法。这是一个适用于大约 7000 名学生的网络应用程序,当他们在 4 个校园网络中的一个上时,他们都将共享相同的传出 IP 地址。目前,失败的登录作为时间戳和 IP 地址以及尝试的用户名(外键)记录在表中,如果用户名不正确,则记录为 NULL。

我们已经想到了一些方法,但都存在安全漏洞或问题:

  • 存储用户代理字符串:学校中的许多计算机都是标准化的,并产生相同的用户代理字符串

  • 存储本地/网络 IP 地址:目前没有可靠且有效的评估方法

  • 给每个用户一个唯一的 ID 并存储在 cookie 中:可以轻松刷新会话、清除缓存、不同浏览器等。

如果有某种方法可以使用 PHP 或 MySQL 可靠地识别小网络地址后面的用户,理想情况下,我们会比较最近从该地址登录尝试的次数。这样我们就可以锁定(服务器端)那个用户。

我想知道拥有较大用户群的网站使用哪些方法有效。

【问题讨论】:

  • 锁定每个帐户,而不是每个 ip。问题解决了。
  • 我没有看到任何网站,即使是主要的托管服务提供商,也没有选择自动执行此操作。他们启用警报,然后手动阻止 IP 地址。
  • “给每个用户一个唯一的ID并存储在cookie中:可以轻松刷新会话,清除缓存,不同浏览器等。” - 实际上,cookie可以被清除;另一方面,会话是服务器端的,对用户来说是唯一的。
  • @Fred-ii-,用户可以清除存储会话ID的cookie,这将强制Web服务器为用户生成一个新会话。与使用 cookie 的问题相同。
  • @David 旁注:stackoverflow.com/a/1085792

标签: php mysql pdo brute-force


【解决方案1】:

这里的标准方法是tar pit。只需放慢它们的速度,这样就无法暴力攻击帐户。

另一种方法是在对特定帐户进行如此多次失败尝试后使用验证码。唯一的缺点是,如果受害者必须为其帐户输入验证码,他们就会知道自己受到了攻击。

这假设每个人都有一个强密码。强制使用强(长、非字典)密码。

使用这种方法,很少需要锁定受到攻击的帐户,但您可以根据需要通知他们。

【讨论】:

    【解决方案2】:

    我认为我们将进行时间锁定/验证码组合。

    • 当用户尝试使用同一帐户登录 > 3 次时,系统会要求他们在登录时完成内部验证码。

    • 如果他们两次未能通过验证码,该帐户将被锁定在该 IP 地址 5 分钟。 (然后是 10 次,然后是 20 次,等等 - 每次后续尝试)

    • 在 8 次或更多尝试失败的情况下 - 可以通过电子邮件向用户发送包含唯一标识符的链接,使他们可以跳过锁定期和/或重置密码。类似于忘记密码,但他们也可以根据需要保留密码。

    额外措施

    • 如果超过 3 个不同的 IP 地址尝试登录一个帐户但在半小时内没有成功 - 在接下来的一个小时内强制启用 CAPTCHA,或者直到从最初的 3 个 IP 地址之一成功登录。

    这种方法的好处是,真正的用户不会因为暴力尝试失败而被锁定,尤其是当攻击者在不同的网络上时。

    【讨论】:

    • 我总是对内部验证码持“怀疑态度”。我知道有人尝试过,这是his feat。虽然他确实为角色添加了一些“线条”,但通过应用一些过滤器仍然很容易绕过它……所以大多数时候我建议使用一个众所周知的验证码系统,该系统已被证明足够强大跨度>
    • 实际上,在这个网络应用程序上破解用户帐户的动机并不大 - 话虽如此 -> Captcha 更像是“慢下来”对于第四次和第五次登录尝试。为您的建议喝彩,我们可能会接受它(尽管偏好是服务器不依赖任何其他服务)
    【解决方案3】:

    最近我读到了关于识别用户唯一性的画布技巧。我没有完全理解这个概念,但这与canvas在每台机器上渲染东西时有非常小的差异有关。 addthis.com 例如用这个来识别。 IMO,这不是一个非常温和的解决方案。

    该技术称为:Canvas Fingerprinting。

    这里有一个很好的资源:@​​987654321@

    【讨论】:

    • 恐怕 HTML5 Canvas Fingerprinting 不会是一个可接受的解决方案,因为一半的校园计算机仍在运行不完全支持 HTML4 的旧版本 IE,更不用说 5。
    【解决方案4】:

    如果客户端足够新,您也许可以利用 webRTC。这是一个将整个数据包转储到屏幕并在控制台中记录单个 IP 地址的示例。您可以使用 javascript 将它们发送到服务器并使用它们来阻止。

    <html>
     <head>
      <title>Test</title>
      <script>
         function grepSDP(sdp) {
           var hosts = [];
           sdp.split('\r\n').forEach(function (line) {
               if (~line.indexOf('a=candidate')) {
                   var parts = line.split(' '),
                       addr = parts[4],
                       type = parts[7];
                   if (type === 'host')
                       console.log(addr);
               } else if (~line.indexOf('c=')) {
                   var parts = line.split(' '),
                   addr = parts[2];
                   console.log(addr);
               }
        });
       }
    
       var peer = new webkitRTCPeerConnection({'iceServers': [{'url': 'stun:stun.services.mozilla.com'}]});
       peer.createOffer(function(sdp) { peer.setLocalDescription(sdp); }, function(err) { console.error(err); }, {});
       setTimeout(function() {
            grepSDP(peer.localDescription.sdp);
            document.getElementById("localdescription").innerHTML = peer.localDescription.sdp;
           }, 500);
      </script>
     </head>
     <body>
      Local description:
      <div id="localdescription">
     </body>
    </html>
    

    【讨论】:

    • 这里有两个主要缺陷:用户可以禁用 JavaScript,以及欺骗 IP 信息。
    • 我想您可以强制他们启用 JavaScript,否则应用程序将失败。欺骗可能/将是可能的。我想这取决于您要保护的内容。另一种选择是使用 ssl 传输的 java 实现,因此它们无法欺骗。
    猜你喜欢
    • 2012-03-05
    • 2011-04-04
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多