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
Oct 09 PHP
windows下PHP APACHE MYSQ完整配置
Jan 02 PHP
dedecms防止FCK乱格式化你的代码的修改方法
Mar 17 PHP
php自动跳转中英文页面
Jul 29 PHP
MySQL连接数超过限制的解决方法
Jul 17 PHP
php生成静态文件的多种方法分享
Jul 17 PHP
使用phpQuery采集网页的方法
Nov 13 PHP
yii实现创建验证码实例解析
Jul 31 PHP
Win7下手动安装apache2.2、php5.4笔记
Apr 03 PHP
PHP之预定义接口详解
Jul 29 PHP
php处理静态页面:页面设置缓存时间实例
Jun 22 PHP
thinkPHP通用控制器实现方法示例
Nov 23 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为什么选mysql作为数据库? Mysql 创建用户方法
2007/07/02 PHP
Laravel 4 初级教程之Pages、表单验证
2014/10/30 PHP
Zend Framework开发入门经典教程
2016/03/23 PHP
在网页里看flash的trace数据的js类
2009/01/10 Javascript
JavaScript 字符串乘法
2009/08/20 Javascript
javascript 冒泡排序 正序和倒序实现代码
2010/12/14 Javascript
写得不错的jquery table鼠标经过变色代码
2013/09/27 Javascript
jQuery实现仿Alipay支付宝首页全屏焦点图切换特效
2015/05/04 Javascript
JavaScript实现页面跳转的方式汇总
2016/05/16 Javascript
有关jQuery中parent()和siblings()的小问题
2016/06/01 Javascript
jQuery插件echarts实现的去掉X轴、Y轴和网格线效果示例【附demo源码下载】
2017/03/04 Javascript
Vue自定义事件(详解)
2017/08/19 Javascript
layui表格数据复选框回显设置方法
2019/09/13 Javascript
vue父子组件的通信方法(实例详解)
2019/11/10 Javascript
小程序瀑布流组件实现翻页与图片懒加载
2020/05/19 Javascript
[55:25]2018DOTA2亚洲邀请赛3月29日 小组赛A组 VG VS OG
2018/03/30 DOTA
Python中使用中文的方法
2011/02/19 Python
Python利用多进程将大量数据放入有限内存的教程
2015/04/01 Python
Python3.6.2调用ffmpeg的方法
2019/01/10 Python
Pytorch 实现sobel算子的卷积操作详解
2020/01/10 Python
在python中使用pymysql往mysql数据库中插入(insert)数据实例
2020/03/02 Python
Django多数据库配置及逆向生成model教程
2020/03/28 Python
numpy库reshape用法详解
2020/04/19 Python
PyInstaller的安装和使用的详细步骤
2020/06/02 Python
Python 创建守护进程的示例
2020/09/29 Python
利用css3实现的简单的鼠标悬停按钮
2014/11/04 HTML / CSS
韩国知名的家庭购物网站:CJmall
2016/08/01 全球购物
世界上最大的皮肤科医生拥有和经营的美容网站:LovelySkin
2021/01/03 全球购物
十岁生日父母答谢词
2014/01/18 职场文书
《蒙娜丽莎之约》教学反思
2014/02/27 职场文书
2013年最新自荐信范文
2014/06/23 职场文书
法制演讲稿
2014/09/10 职场文书
2014年个人技术工作总结
2014/12/08 职场文书
财务工作失误检讨书
2015/02/19 职场文书
安全教育主题班会教案
2015/08/12 职场文书
解决Pytorch中关于model.eval的问题
2021/05/22 Python