php如何预防sql注入

  • 内容
  • 评论
  • 相关

一.什么是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的方式注入,虽然能取出来一条记录,但是输入密码必须和这条记录的匹配才能验证成功,也能起到预防的效果。




本文标签:

版权声明:若无特殊注明,本文皆为《菜鸟站长》原创,转载请保留文章出处。

本文链接:php如何预防sql注入 - https://www.wlphp.com/?post=199

发表评论

电子邮件地址不会被公开。 必填项已用*标注