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中在数据库中保存Checkbox数据(1)
Oct 09 PHP
phpMyAdmin链接MySql错误 个人解决方案
Dec 28 PHP
简单的php写入数据库类代码分享
Jul 26 PHP
php数组函数序列之end() - 移动数组内部指针到最后一个元素,并返回该元素的值
Oct 31 PHP
php 常用算法和时间复杂度
Jul 01 PHP
PHP实现将浏览历史页面网址保存到cookie的方法
Jan 26 PHP
smarty模板引擎之分配数据类型
Mar 30 PHP
PHP中Http协议post请求参数
Nov 02 PHP
PHP使Laravel为JSON REST API返回自定义错误的问题
Oct 16 PHP
phpinfo无法显示的原因及解决办法
Feb 15 PHP
PHP实时统计中文字数和区别
Feb 28 PHP
Laravel 自动生成验证的实例讲解:login / logout
Oct 14 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
对squid中refresh_pattern的一些理解和建议
2009/04/17 PHP
PHP冒泡排序算法代码详细解读
2011/07/17 PHP
PHP daddslashes 使用方法介绍
2012/10/26 PHP
支持中文的PHP按字符串长度分割成数组代码
2015/05/17 PHP
PHP实现查询两个数组中不同元素的方法
2016/02/23 PHP
PHP工厂模式、单例模式与注册树模式实例详解
2019/06/03 PHP
Jquery 弹出层插件实现代码
2009/10/24 Javascript
javascript拖拽上传类库DropzoneJS使用方法
2013/12/05 Javascript
Jquery easyUI 更新行示例
2014/03/06 Javascript
js中自定义方法实现停留几秒sleep
2014/07/11 Javascript
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
JavaScript Ajax编程 应用篇
2016/07/02 Javascript
AngularJS表格样式简单设置方法示例
2017/03/03 Javascript
JS获取短信验证码倒计时的实现代码
2017/05/22 Javascript
详解js常用分割取字符串的方法
2019/05/15 Javascript
VueJS 取得 URL 参数值的方法
2019/07/19 Javascript
微信小程序实现手势滑动卡片效果
2019/08/26 Javascript
Element-Ui组件 NavMenu 导航菜单的具体使用
2019/10/24 Javascript
vue el-tree 默认展开第一个节点的实现代码
2020/05/15 Javascript
[08:08]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY
2014/06/25 DOTA
windows系统中python使用rar命令压缩多个文件夹示例
2014/05/06 Python
解决matplotlib库show()方法不显示图片的问题
2018/05/24 Python
python traceback捕获并打印异常的方法
2018/08/31 Python
Python之循环结构
2019/01/15 Python
对pytorch中的梯度更新方法详解
2019/08/20 Python
python爬取代理IP并进行有效的IP测试实现
2020/10/09 Python
使用css3制作动感导航条示例
2014/01/26 HTML / CSS
大学生志愿者感言
2014/01/15 职场文书
计算机专业毕业生自我鉴定
2014/01/16 职场文书
村支部书记群众路线对照检查材料思想汇报
2014/10/08 职场文书
出国留学导师推荐信
2015/03/26 职场文书
《静夜思》教学反思
2016/02/17 职场文书
创业计划书之蛋糕店
2019/08/29 职场文书
导游词之张家口
2019/12/13 职场文书
canvas绘制折线路径动画实现
2021/05/12 Javascript
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL