探讨php中防止SQL注入最好的方法是什么


Posted in PHP onJune 10, 2013

如果用户输入的是直接插入到一个SQL语句中的查询,应用程序会很容易受到SQL注入,例如下面的例子:

$unsafe_variable = $_POST['user_input'];
mysql_query("INSERT INTO table (column) VALUES ('" . $unsafe_variable . "')");

这是因为用户可以输入类似VALUE“); DROP TABLE表; - ,使查询变成:
INSERT INTO table (column) VALUES('VALUE'); DROP TABLE table;'

我们应该怎么防止这种情况呢?请看下面
使用预备义语句和参数化查询。对于带有任何参数的sql语句都会被发送到数据库服务器,并被解析!对于攻击者想要恶意注入sql是不可能的!
实现这一目标基本上有两种选择:
1.使用PDO(PHP Data Objects ):
$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(PHP数据对象)
注意当使用PDO访问MySQL数据库真正的预备义语句并不是默认使用的!为了解决这个问题,你必须禁用仿真准备好的语句。
使用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);

在上面例子中错误模式ERRMODE不是严格必须的,但是建议添加它。当运行出错产生致命错误时,这种方法脚本不会停止。并给开发人员捕捉任何错误的机会(当抛出PDOException异常时)。
setAttribute()那一行是强制性的,它告诉PDO禁用仿真预备义语句,使用真正的预备义语句。这可以确保语句和值在发送给MySQL数据库服务器前不被PHP解析(攻击者没有机会注入恶意的SQL).
当然你可以在构造函数选项中设置字符集参数,特别注意'老'的PHP版本(5.3.6)会在DSN中忽略掉字符集参数。

Explanation(解释)
在你传递的sql预备义语句 被数据库服务器解析和编译会发生什么?通过指定的字符(在上面例子中像a?或者像:name)告诉数据库引擎你想要过滤什么.然后调用execute执行结合好的预备义语句和你指定的参数值.

这里最重要的是,该参数值是和预编译的语句结合的,而不是和一个SQL字符串.SQL注入的工作原理是通过欺骗手段创建的SQL脚本包括恶意字符串发送到数据库.因此,通过发送实际的分开的sql参数,你会降低风险.使用准备好的语句时,你发送的任何参数,将只被视为字符串(虽然数据库引擎可能会做一些参数的优化,当然最终可能会为数字).在上面的例子中,如果变量$name包含'sarah';DELETE * FROM employees,结果只会是一个搜索的字符串"'sarah';DELETE * FROM employees",你不会得到一个空表。

使用准备好的语句的另一个好处是,如果你在同一会话中多次执行相同的语句,这将只被解析和编译一次,给你一些的速度增长。
哦,既然你问如何进行插入,这里是一个例子(使用PDO):

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');
$preparedStatement->execute(array(':column' => $unsafeValue));
PHP 相关文章推荐
php基础知识:类与对象(4) 范围解析操作符(::)
Dec 13 PHP
PHP 地址栏信息的获取代码
Jan 07 PHP
php不用内置函数对数组排序的两个算法代码
Feb 08 PHP
由php的call_user_func传reference引发的思考
Jul 23 PHP
PHP正确解析UTF-8字符串技巧应用
Nov 07 PHP
ASP和PHP实现生成网站快捷方式并下载到桌面的方法
May 08 PHP
php抽象类使用要点与注意事项分析
Feb 09 PHP
php获取twitter最新消息的方法
Apr 14 PHP
PHP中的命名空间详细介绍
Jul 02 PHP
thinkphp实现163、QQ邮箱收发邮件的方法
Dec 18 PHP
PHP实现获取并生成数据库字典的方法
May 04 PHP
PHP rsa加密解密算法原理解析
Dec 09 PHP
php防注入,表单提交值转义的实现详解
Jun 10 #PHP
PHP获取当前页面完整URL的实现代码
Jun 10 #PHP
如何判断php数组的维度
Jun 10 #PHP
joomla jce editor 解决上传中文名文件失败问题
Jun 09 #PHP
php缩放图片(根据宽高的等比例缩放)实例介绍
Jun 09 #PHP
探讨php define()函数及defined()函数使用详解
Jun 09 #PHP
如何用php获取程序执行的时间
Jun 09 #PHP
You might like
PHP数组对比函数,存在交集则返回真,否则返回假
2011/02/03 PHP
php中取得URL的根域名的代码
2011/03/23 PHP
PHP获取搜索引擎关键字来源的函数(支持百度和谷歌等搜索引擎)
2012/10/03 PHP
PHP简单实现“相关文章推荐”功能的方法
2014/07/19 PHP
php中使用base HTTP验证的方法
2015/04/20 PHP
php实现文本数据导入SQL SERVER
2015/05/17 PHP
php获取文件后缀的9种方法
2016/03/22 PHP
ThinkPHP框架下微信支付功能总结踩坑笔记
2019/04/10 PHP
javascript使用eval或者new Function进行语法检查
2010/10/16 Javascript
js定义对象或数组直接量时各浏览器对多余逗号的处理(json)
2011/03/05 Javascript
jQuery $.get 的妙用 访问本地文本文件
2012/07/12 Javascript
JS控制网页动态生成任意行列数表格的方法
2015/03/09 Javascript
JS动态给对象添加属性和值的实现方法
2016/10/21 Javascript
Javascript设计模式之装饰者模式详解篇
2017/01/17 Javascript
JavaScript用200行代码制作打飞机小游戏实例
2017/06/21 Javascript
快速理解 JavaScript 中的 LHS 和 RHS 查询的用法
2017/08/24 Javascript
js中apply与call简单用法详解
2017/11/06 Javascript
nodejs实现爬取网站图片功能
2017/12/14 NodeJs
让你5分钟掌握9个JavaScript小技巧
2018/06/09 Javascript
React中使用外部样式的3种方式(小结)
2019/05/28 Javascript
微信小程序实现原生步骤条
2019/07/25 Javascript
Vue+Java 通过websocket实现服务器与客户端双向通信操作
2020/09/22 Javascript
[13:39]2014 DOTA2华西杯精英邀请赛 5 25 NewBee VS DK第一场
2014/05/26 DOTA
python显示天气预报
2014/03/02 Python
python原类、类的创建过程与方法详解
2019/07/19 Python
Python socket模块ftp传输文件过程解析
2019/11/05 Python
Django通用类视图实现忘记密码重置密码功能示例
2019/12/17 Python
Python hashlib常见摘要算法详解
2020/01/13 Python
女孩每月服装订阅盒:kidpik
2019/04/17 全球购物
俄罗斯玩具、儿童用品、儿童服装和鞋子网上商店:MyToys.ru
2019/10/14 全球购物
温泉秘密:Onsen Secret
2020/07/06 全球购物
自荐信格式写作方法有哪些呢
2013/11/20 职场文书
节能减耗标语
2014/06/21 职场文书
师德自我剖析材料范文
2014/10/06 职场文书
2016党员三严三实心得体会
2016/01/15 职场文书
python_tkinter事件类型详情
2022/03/20 Python