PHP使用PDO实现mysql防注入功能详解


Posted in PHP onDecember 20, 2019

本文实例讲述了PHP使用PDO实现mysql防注入功能。分享给大家供大家参考,具体如下:

1、什么是注入攻击

例如下例:

前端有个提交表格:

<form action="test.php" method="post">
    姓名:<input name="username" type="text">
    密码:<input name="password" type="password">
    <input type="submit" value="登陆">
  </form>

后台的处理如下:

<?php
  $username=$_POST["username"];
  $password=$_POST["password"];
  $age=$_POST["age"];
  //连接数据库,新建PDO对象
  $pdo=new PDO("mysql:host=localhost;dbname=phpdemo","root","1234");
  
  $sql="select * from login WHERE username='{$username}' AND password='{$password}' ";
  echo $sql;
  $stmt=$pdo->query($sql);
  //rowCount()方法返回结果条数或者受影响的行数
  if($stmt->rowCount()>0){ echo "登陆成功!"};

正常情况下,如果你输入姓名为小王,密码xiaowang,会登陆成功,sql语句如下:select * from login WHERE username='小王' AND password='xiaowang' 登陆成功!

但是如果你输入姓名为 ' or 1=1 #,密码随便输一个,也会登陆成功,sql语句为:select * from login WHERE username='' or 1=1 #' AND password='xiaowang' 登陆成功!

可以看到username='' or 1=1,#注释调了之后的password语句,由于 1=1恒成立,因此这条语句会返回大于1的结果集,从而使验证通过。

2、使用quote过滤特殊字符,防止注入

在sql语句前加上一行,将username变量中的‘等特殊字符过滤,可以起到防止注入的效果

//通过quote方法,返回带引号的字符串,过滤调特殊字符
$username=$pdo->quote($username);
$sql="select * from login WHERE username={$username} AND password='{$password}' ";
echo $sql;
$stmt=$pdo->query($sql);
//rowCount()方法返回结果条数或者受影响的行数
if($stmt->rowCount()>0){
  echo "登陆成功!";
};

sql语句为:select * from login WHERE username='\' or 1=1 #' AND password='xiaowang'

可以看到“'”被转义\',并且自动为变量$username加上了引号

3、通过预处理语句传递参数,防注入

//通过占位符:username,:password传递值,防止注入
$sql="select * from login WHERE username=:username AND password=:password";
$stmt=$pdo->prepare($sql);
//通过statement对象执行查询语句,并以数组的形式赋值给查询语句中的占位符
$stmt->execute(array(':username'=>$username,':password'=>$password));
echo $stmt->rowCount();

其中的占位符也可以为?

//占位符为?
$sql="select * from login WHERE username=? AND password=?";
$stmt=$pdo->prepare($sql);
//数组中参数的顺序与查询语句中问号的顺序必须相同
$stmt->execute(array($username,$password));
echo $stmt->rowCount();

4、通过bind绑定参数

bindParam()方法绑定一个变量到查询语句中的参数:  

$sql="insert login(username,password,upic,mail) values(:username,:password,:age,:mail)";
$stmt=$pdo->prepare($sql);
//第三个参数可以指定参数的类型PDO::PARAM_STR为字符串,PDO::PARAM_INT为整型数
$stmt->bindParam(":username",$username,PDO::PARAM_STR);
$stmt->bindParam(":password",$password,PDO::PARAM_STR);
$stmt->bindParam(":age",$age,PDO::PARAM_INT);
//使用bindValue()方法绑定一个定值
$stmt->bindValue(":mail",'default@qq.com');
$stmt->execute();
echo $stmt->rowCount();

使用问号做占位符:

$sql="insert login(username,password,mail) values(?,?,?)";//注意不是中文状态下的问号? 
$stmt=$pdo->prepare($sql); //按照?的顺序绑定参数值 
$stmt->bindParam(1,$username); 
$stmt->bindParam(2,$password); 
$stmt->bindValue(3,'default@qq.com'); 
$stmt->execute(); 
echo $stmt->rowCount();

使用其中bindValue()方法给第三个占位符绑定一个常量'default@qq.com',它不随变量的变化而变化。

bindColumn()方法绑定返回结果集的一列到变量:   

$sql='SELECT * FROM user';
$stmt=$pdo->prepare($sql);
$stmt->execute();
$stmt->bindColumn(2,$username);
$stmt->bindColumn(4,$email);
while($stmt->fetch(PDO::FETCH_BOUND)){
  echo '用户名:'.$username.",邮箱:".$email.'<hr/>';
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php用数组返回无限分类的列表数据的代码
Aug 08 PHP
php跨域cookie共享使用方法
Feb 20 PHP
PHP错误Cannot use object of type stdClass as array in错误的解决办法
Jun 12 PHP
php递归调用删除数组空值元素的方法
Apr 28 PHP
PHP批量去除BOM头代码分享
Jun 26 PHP
ThinkPHP和UCenter接口冲突的解决方法
Jul 25 PHP
PHP将身份证正反面两张照片合成一张图片的代码
Apr 08 PHP
PHP PDOStatement::execute讲解
Jan 31 PHP
PHP chop()函数讲解
Feb 11 PHP
Laravel自动生成UUID,从建表到使用详解
Oct 24 PHP
ThinkPHP6.0如何利用自定义验证规则规范的实现登陆
Dec 16 PHP
Linux系统下安装PHP7.3版本
Jun 26 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
Dec 20 #PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
Dec 20 #PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
Dec 20 #PHP
Laravel框架处理用户的请求操作详解
Dec 20 #PHP
PHP上传图片到数据库并显示的实例代码
Dec 20 #PHP
ThinkPHP类似AOP思想的参数验证的实现方法
Dec 18 #PHP
Laravel jwt 多表(多用户端)验证隔离的实现
Dec 18 #PHP
You might like
PHP无刷新上传文件实现代码
2011/09/19 PHP
php网站被挂木马后的修复方法总结
2014/11/06 PHP
ThinkPHP里用U方法调用js文件实例
2015/06/18 PHP
Zend Framework教程之模型Model用法简单实例
2016/03/04 PHP
实例讲解php数据访问
2016/05/09 PHP
php安全配置记录和常见错误梳理(总结)
2017/03/28 PHP
Windows平台实现PHP连接SQL Server2008的方法
2017/07/26 PHP
PHP替换Word中变量并导出PDF图片的实现方法
2020/11/26 PHP
web前端设计师们常用的jQuery特效插件汇总
2014/12/07 Javascript
jQuery 调用WebService 实例讲解
2016/06/28 Javascript
Js 获取、判断浏览器版本信息的简单方法
2016/08/08 Javascript
关于JavaScript和jQuery的类型判断详解
2016/10/08 Javascript
Bootstrap栅格系统的使用和理解2
2016/12/14 Javascript
jquery Form轻松实现文件上传
2017/05/24 jQuery
vue.js如何将echarts封装为组件一键使用详解
2017/10/10 Javascript
vue iView 上传组件之手动上传功能
2018/03/16 Javascript
angular 服务随记小结
2019/05/06 Javascript
vue中get请求如何传递数组参数的方法示例
2019/11/08 Javascript
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
python并发2之使用asyncio处理并发
2017/12/21 Python
Python实现判断并移除列表指定位置元素的方法
2018/04/13 Python
python处理数据,存进hive表的方法
2018/07/04 Python
python 计算一个字符串中所有数字的和实例
2019/06/11 Python
使用Pyhton 分析酒店针孔摄像头
2020/03/04 Python
python selenium自动化测试框架搭建的方法步骤
2020/06/14 Python
python3.7 openpyxl 在excel单元格中写入数据实例
2020/09/01 Python
python中@property的作用和getter setter的解释
2020/12/22 Python
详解如何将 Canvas 绘制过程转为视频
2021/01/25 HTML / CSS
来自南加州灵感的工作和娱乐服装:TravisMathew
2019/05/01 全球购物
PHP经典面试题
2016/09/03 面试题
经济信息管理专业大学生求职信
2013/09/27 职场文书
如何打造一封优秀的留学推荐信
2014/01/25 职场文书
二年级评语大全
2014/04/23 职场文书
钱塘江大潮导游词
2015/02/03 职场文书
小学2016年“我们的节日·重阳节”活动总结
2016/04/01 职场文书
Java 常见的限流算法详细分析并实现
2022/04/07 Java/Android