PHP中怎样防止SQL注入分析


Posted in PHP onOctober 23, 2014

本文实例分析了PHP中怎样防止SQL注入。分享给大家供大家参考。具体分析如下:

一、问题描述:

如果用户输入的数据在未经处理的情况下插入到一条SQL查询语句,那么应用将很可能遭受到SQL注入攻击,正如下面的例子:

$unsafe_variable = $_POST['user_input']; 

 

mysql_query("INSERT INTO `table` (`column`) VALUES ('" . $unsafe_variable . "')");

因为用户的输入可能是这样的:

value'); DROP TABLE table;--

那么SQL查询将变成如下:

INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')

对此应该采取哪些有效的方法来防止SQL注入?

二、解决方法分析:

使用预处理语句和参数化查询。预处理语句和参数分别发送到数据库服务器进行解析,参数将会被当作普通字符处理。这种方式使得攻击者无法注入恶意的SQL。 你有两种选择来实现该方法:

1、使用PDO:

$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');

 

$stmt->execute(array('name' => $name));

 

foreach ($stmt as $row) {

    // do something with $row

}

2、使用mysqli:

$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');

$stmt->bind_param('s', $name);

 

$stmt->execute();

 

$result = $stmt->get_result();

while ($row = $result->fetch_assoc()) {

    // do something with $row

}

三、PDO

注意,在默认情况使用PDO并没有让MySQL数据库执行真正的预处理语句(原因见下文)。为了解决这个问题,你应该禁止PDO模拟预处理语句。一个正确使用PDO创建数据库连接的例子如下:

$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');

 

$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

在上面的例子中,报错模式(ATTR_ERRMODE)并不是必须的,但建议加上它。这样,当发生致命错误(Fatal Error)时,脚本就不会停止运行,而是给了程序员一个捕获PDOExceptions的机会,以便对错误进行妥善处理。 然而,第一个setAttribute()调用是必须的,它禁止PDO模拟预处理语句,而使用真正的预处理语句,即有MySQL执行预处理语句。这能确保语句和参数在发送给MySQL之前没有被PHP处理过,这将使得攻击者无法注入恶意SQL。了解原因,可参考前面这篇文章:PDO防注入原理分析以及使用PDO的注意事项。 注意在老版本的PHP(<5.3.6),你无法通过在PDO的构造器的DSN上设置字符集,参考:silently ignored the charset parameter 。

四、解析

当你将SQL语句发送给数据库服务器进行预处理和解析时发生了什么?通过指定占位符(一个?或者一个上面例子中命名的 :name),告诉数据库引擎你想在哪里进行过滤。当你调用execute的时候,预处理语句将会与你指定的参数值结合。 关键点就在这里:参数的值是和经过解析的SQL语句结合到一起,而不是SQL字符串。SQL注入是通过触发脚本在构造SQL语句时包含恶意的字符串。所以,通过将SQL语句和参数分开,你防止了SQL注入的风险。任何你发送的参数的值都将被当作普通字符串,而不会被数据库服务器解析。回到上面的例子,如果$name变量的值为 'Sarah'; DELETE FROM employees ,那么实际的查询将是在 employees 中查找 name 字段值为 'Sarah'; DELETE FROM employees 的记录。 另一个使用预处理语句的好处是:如果你在同一次数据库连接会话中执行同样的语句许多次,它将只被解析一次,这可以提升一点执行速度。 如果你想问插入该如何做,请看下面这个例子(使用PDO):

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

 

$preparedStatement->execute(array('column' => $unsafeValue));

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

PHP 相关文章推荐
不错的一篇面向对象的PHP开发模式(简写版)
Mar 15 PHP
PHP中查询SQL Server或Sybase时TEXT字段被截断的解决方法
Mar 10 PHP
PHP最常用的ini函数分析 针对PHP.ini配置文件
Apr 22 PHP
php懒人函数 自动添加数据
Jun 28 PHP
phpExcel导出大量数据出现内存溢出错误的解决方法
Feb 28 PHP
php源代码安装常见错误与解决办法分享
May 28 PHP
PHP中$_SERVER的详细参数与说明介绍
Oct 26 PHP
PHP延迟静态绑定示例分享
Jun 22 PHP
yii的CURD操作实例详解
Dec 04 PHP
PHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIF
Feb 19 PHP
PHP常见字符串处理函数用法示例【转换,转义,截取,比较,查找,反转,切割】
Dec 24 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
Aug 28 PHP
PDO防注入原理分析以及使用PDO的注意事项总结
Oct 23 #PHP
常用PHP框架功能对照表
Oct 23 #PHP
C/S和B/S两种架构区别与优缺点分析
Oct 23 #PHP
php中字符串和正则表达式详解
Oct 23 #PHP
PHP制作3D扇形统计图以及对图片进行缩放操作实例
Oct 23 #PHP
PHP制作图形验证码代码分享
Oct 23 #PHP
PHP链接MySQL的常用扩展函数
Oct 23 #PHP
You might like
把77A收信机改造成收音机
2021/03/02 无线电
sphinx增量索引的一个问题
2011/06/14 PHP
Thinkphp5 如何隐藏入口文件index.php(URL重写)
2019/10/16 PHP
Laravel手动返回错误码示例
2019/10/22 PHP
ASP SQL防注入的方法
2008/12/25 Javascript
JavaScript的parseInt 取整使用
2011/05/09 Javascript
浅析IE10兼容性问题(frameset的cols属性)
2014/01/03 Javascript
浅谈js 闭包引起的内存泄露问题
2015/06/22 Javascript
谈谈Jquery中的children find 的区别有哪些
2015/10/19 Javascript
基于jQuery仿淘宝产品图片放大镜特效
2020/10/19 Javascript
再次谈论React.js实现原生js拖拽效果引起的一系列问题
2016/04/03 Javascript
jQuery弹出遮罩层效果完整示例
2016/09/13 Javascript
微信小程序 使用canvas制作K线实例详解
2017/01/12 Javascript
Vue2.2.0+新特性整理及注意事项
2018/08/22 Javascript
浅谈vue后台管理系统权限控制思考与实践
2018/12/19 Javascript
Vue 子组件与数据传递问题及注意事项
2019/07/11 Javascript
JavaScript随机数的组合问题案例分析
2020/05/16 Javascript
vue+elementUI(el-upload)图片压缩,默认同比例压缩操作
2020/08/10 Javascript
Python类的多重继承问题深入分析
2014/11/09 Python
Python ValueError: invalid literal for int() with base 10 实用解决方法
2015/06/21 Python
Python实现购物程序思路及代码
2017/07/24 Python
Python中类的初始化特殊方法
2017/12/01 Python
python调用matlab的m自定义函数方法
2019/02/18 Python
使用python判断jpeg图片的完整性实例
2019/06/10 Python
使用Python轻松完成垃圾分类(基于图像识别)
2019/07/09 Python
python下的opencv画矩形和文字注释的实现方法
2019/07/09 Python
python 多进程队列数据处理详解
2019/12/23 Python
Python使用struct处理二进制(pack和unpack用法)
2020/11/12 Python
英国花园家具中心:Garden Furniture Centre
2017/08/24 全球购物
Fox Racing官方网站:越野摩托车和山地自行车装备和服装
2019/12/23 全球购物
Athleta官网:购买女士瑜伽服、技术运动服和休闲运动服
2020/11/12 全球购物
圣诞节红领巾广播稿
2014/02/03 职场文书
学生请假条
2014/04/11 职场文书
反邪教宣传工作方案
2014/05/07 职场文书
python 爬取华为应用市场评论
2021/05/29 Python
Apache Pulsar结合Hudi构建Lakehouse方案分析
2022/03/31 Servers