PHP菜鸟博客_共同学习分享PHP技术心得【PHP爱好者】
php如何预防sql注入
2019-6-26 菜鸟站长


一.什么是sql注入



sql.jpg



打印下sql发现:



tp代码:



$plat_accountinfo = Db::table("plat_account")->where("accountname='$accountname' and accountpassword='$accountpassword' and isdel=0")->find();



最终转化成原生sql:



SELECT * FROM `plat_account` WHERE  (  accountname='admin' or '1'='1' and accountpassword='abe8bbd24e9ccb7595623a512741bc85' and isdel=0 ) LIMIT 1



admin' or '1'='1 这一部分代码里面是个变量,拼接进去正好变成了上面的写法。







二.解决方法1



给用户名密码变量转义下,把里面的',字符前面增加一个\



$accountname = isset($param['accountname']) ? trim($param['accountname']) : '';

$accountpassword = isset($param['accountpassword']) ? trim($param['accountpassword']) : '';

$accountname=addslashes($accountname);

$accountpassword=addslashes($accountpassword);



然后再看下sql:



SELECT * FROM `plat_account` WHERE  (  accountname='admin\' or \'1\'=\'1' and accountpassword='abe8bbd24e9ccb7595623a512741bc85' and isdel=0 ) LIMIT 1



$accountname变量内容里面的'被增加了转义字符,’admin\' or \'1\'=\'1  ,这样就被限制住了。



三.解决方法2



tp框架可以把where条件改成数组模式



$where['accountname']=$accountname;

$where['accountpassword']=$accountpassword;

$plat_accountinfo = Db::table("plat_account")->where($where)->find();



最终的sql



SELECT * FROM `plat_account` WHERE  `accountname` = 'admin\' or \'1\'=\'1'  AND `accountpassword` = 'abe8bbd24e9ccb7595623a512741bc85' LIMIT 1



也能实现类似的效果。



四.解决方法3



        //先根据用户名获取密码,然后把传过来的明文密码加密后和数据库取出来的做对比验证

        $plat_accountinfo = Db::table("plat_account")->where("accountname='$accountname'  and isdel=0")->find();

        if($plat_accountinfo['accountpassword']!=$accountpassword){

            $rt['sta'] = 0;

            $rt['msg'] = "对不起密码不匹配!";

            echo json_encode($rt);

            die;

        }

     



通过用户名等于admin\' or \'1\'=\'1的方式注入,虽然能取出来一条记录,但是输入密码必须和这条记录的匹配才能验证成功,也能起到预防的效果。














发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容