07-SQL-登录次数限制--爆破防护

一、基本思路

在前述攻防的过程中,我们从最开始写一个简单的登录页面和后台功能开始,

到发现SQL注入漏洞,万能验证码,爆破等漏洞开始,

一路修改代码对漏洞进行防护,一路又使用新的手段进行破解,最终只剩下爆破这一个漏洞了,

只要限制用户登录失败的次数,那么就可以从根本上防止暴力破解

1)需要在数据库中记录某个用户的登录失败的次数,每登录失败一次,则+1

2)需要在数据库中记录某个用户最后一次登录时间,用于判断是否接触限制

3)每一次登录时,只要用户名是存在的,都需要从数据库里面取得这两个值,从而进行判断

二、技术准备

在数据库中添加两列,failcount,lasttime,如下图所示

1.核心的SQL语句操作

同时更新两个字段并更新时间为现在:update user set failcount=failcount+1 lasttime=now() where userid=?
比较两个时间的差值,单位可以是分或者是秒等:select lasttime,now(),TIMSTAMPDIFF(MINUTE,lasttime,NOW()) from user;

2.在php中处理时间

完整代码展示-利用登录次数的限制从而达到防止爆破的漏洞

<?php
/**
 * 本代码解决用户登录失败的限制问题,更加完整的解决登录模块的爆破和其他漏洞
 */
    include "common.php";

    // 获取用户提交的登录请求的数据
    // 使用addslashes函数对用户名进行转义
    $username = $_POST['username'];
    $password = $_POST['password'];
    $vcode = $_POST['vcode'];

    // 验证码的验证

    // 此处启用了万能验证码的漏洞==》存在安全漏洞:认证和授权失败
    // if($vcode !== '0000'){
    //     die("vcode-error");
    // }

    // 根据图片验证码进行验证
    if(strtoupper($_SESSION['vcode']) != strtoupper($vcode)){
        die("vcode-error");
    }
    else{
        // 验证码输入成功后,再清空本次session中的验证码
        unset($_SESSION['vcode']);
        // $_SESSION['vcode']='';  不能直接设置为空字符串,否则也可以在请求上提交一个空验证码,实现绕过
    }

    // 无论验证码是否正确,再提交一次请求均清空一次,但是会增加服务器的负担
    unset($_SESSION['vcode']);

    // if(strtoupper($_COOKIE['vcode']) !=strtoupper($vcode)){
    //     die("vcode-error");
    // }


    $conn=create_connection_oop();
    // create_connection_oop()

    // create_connection()是调用common.php中定义的函数,就是数据库连接的
    // $conn = create_connection();
    $sql= "select userid,username,password,role,failcount,TIMESTAMPDIFF(Minute,lasttime,now()) from user where username=?";

    // 基于面向对象和MySQL预处理功能是实现MySQL注入
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s",$username);    // 绑定结果集
    $stmt->bind_result($userid,$username2,$passwrod2,$role,$failcount,$timediff);  //绑定结果参数  $timmdiff得到了相差的分钟数
    $stmt->execute();
    $stmt->store_result();  //获取行数

    // 获取到的行数是否为一,只表示用户名存在
    if($stmt->num_rows == 1 ){    //表明用户存在
        $stmt->fetch();


        // 判断密码是否正确之前,先判断登录次数是否受限
        if ($failcount >= 5 && $timediff <=60){
            die('user-locked');
        }


        //判断密码是否正确之前,先判断登录次数是否受限
        if ($failcount>=5){
            die('user-locked');
        }

        if($password == $password2){
            // 先把failcount重置为零
            if($failcount > 0){
                $sql = "update user set failcount=0 where userid=?";
                $stmt = $conn->prepare($sql);
                $stmt->bind_param("i",$userid);
                $stmt->execute();
            }
            echo "login-pass";
            // 失效的访问控制
            // url绕过
            echo "hello,word";
            // 登录成功后,记录session变量
            $_SESSION['username'] = $username;
            $_SESSION['islogin'] = 'true';
            echo " <script>location.href='welcome.php'</script> "; 
        }
        else{
            $sql = "update user set failcount=failcount+1,lasttime=now() where userid=?";
            $stmt = $conn->prepare($sql);
            $stmt->bind_param("i",$userid);
            $stmt->execute();
            echo "login-fail";
            echo " <script>location.href='login.html'</script> ";

        }
         
    }
    else{
        echo "user-invalid";
        echo " <script>location.href='login.html'</script> ";
    }
    // 关闭数据库
    mysqli_close($conn);
?>

登录模块的各类的防护措施“

验证码:不建议使用图片验证码

登录次数的限制,并记录IP

多因素认证:账密+短信

记录用户常用IP地址区域,如果在不常用区域登录,预警

除了使用session外,也会使用到token

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值