Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 防止多个用户共享IP地址的暴力攻击_Php_Mysql_Pdo_Brute Force - Fatal编程技术网

Php 防止多个用户共享IP地址的暴力攻击

Php 防止多个用户共享IP地址的暴力攻击,php,mysql,pdo,brute-force,Php,Mysql,Pdo,Brute Force,我和我的团队正在用PHP5.5编写一个web应用程序,其中有一个数据库(除其他外)具有用于用户身份验证的典型用户名和密码哈希查找 我们正在寻找防止超过相对数量(比如8)的不正确登录的方法。这是一个供大约7000名学生使用的网络应用程序,当他们在4个校园网络中的一个网络上时,他们将共享相同的传出IP地址。当前,失败的登录将作为时间戳和IP地址以及尝试的用户名(外键)记录在表中,如果用户名不正确,则为NULL 我们已经想到了一些方法,但都会带来安全缺陷或问题: 存储用户代理字符串:许多计算机在各个

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

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

我们已经想到了一些方法,但都会带来安全缺陷或问题:

  • 存储用户代理字符串:许多计算机在各个学校进行标准化,并生成相同的用户代理字符串

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

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

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


我想知道拥有更大用户群的站点有效地使用了哪些方法。

最近我读到了一篇关于识别唯一用户的画布技巧的文章。我并没有完全理解这个概念,但它与画布在每台机器上呈现内容时都有非常小的差异这一事实有关。添加this.com,例如,使用此来识别。这不是一个很温和的解决方案,依我看

这项技术被称为:画布指纹识别


这里有一个很好的参考资料:

最近,我读到了一篇关于识别用户的画布技巧的文章。我并没有完全理解这个概念,但它与画布在每台机器上呈现内容时都有非常小的差异这一事实有关。添加this.com,例如,使用此来识别。这不是一个很温和的解决方案,依我看

这项技术被称为:画布指纹识别


这里有一个很好的资源:

如果客户机足够新,您可以利用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>

试验
功能grepSDP(sdp){
var主机=[];
sdp.split('\r\n').forEach(函数(行){
if(~line.indexOf('a=candidate')){
变量部分=行分割(“”),
地址=零件[4],
类型=零件[7];
如果(类型==‘主机’)
控制台日志(addr);
}else如果(~line.indexOf('c=')){
变量部分=行分割(“”),
地址=零件[2];
控制台日志(addr);
}
});
}
var peer=new-webkirtpeerconnection({'iceServers':[{'url':'stun:stun.services.mozilla.com'}]});
createOffer(函数(sdp){peer.setLocalDescription(sdp);},函数(err){console.error(err);},{});
setTimeout(函数(){
grepSDP(peer.localDescription.sdp);
document.getElementById(“localdescription”).innerHTML=peer.localdescription.sdp;
}, 500);
本地描述:

如果客户机足够新,您可以利用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>

试验
功能grepSDP(sdp){
var主机=[];
sdp.split('\r\n').forEach(函数(行){
if(~line.indexOf('a=candidate')){
变量部分=行分割(“”),
地址=零件[4],
类型=零件[7];
如果(类型==‘主机’)
控制台日志(addr);
}else如果(~line.indexOf('c=')){
变量部分=行分割(“”),
地址=零件[2];
控制台日志(addr);
}
});
}
var peer=new-webkirtpeerconnection({'iceServers':[{'url':'stun:stun.services.mozilla.com'}]});
createOffer(函数(sdp){peer.setLocalDescription(sdp);},函数(err){console.error(err);},{});
setTimeout(函数(){
grepSDP(peer.localDescription.sdp);
document.getElementById(“localdescription”).innerHTML=peer.localdescription.sdp;
}, 500);
本地描述:

我想我们将采用时间锁定/验证码组合

  • 当用户尝试登录同一帐户超过3次时,将要求他们在登录时填写内部验证码

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

  • 在8次或更多尝试失败的情况下,可以通过电子邮件向用户发送包含唯一标识符的链接,该唯一标识符允许用户跳过锁定期和/或重置密码。类似于忘记密码,只是他们也可以保留自己的密码,如果他们愿意的话

附加措施

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

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

我认为我们将采用时间锁定/验证码组合

  • 当用户尝试登录时>