PHP中防止SQL注入方法详解


Posted in PHP onDecember 25, 2014

问题描述:

如果用户输入的数据在未经处理的情况下插入到一条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注入?

 最佳回答(来自Theo):

使用预处理语句和参数化查询。预处理语句和参数分别发送到数据库服务器进行解析,参数将会被当作普通字符处理。这种方式使得攻击者无法注入恶意的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 相关文章推荐
自己动手做一个SQL解释器
Oct 09 PHP
无数据库的详细域名查询程序PHP版(5)
Oct 09 PHP
延长phpmyadmin登录时间的方法
Feb 06 PHP
PHP投票系统防刷票判断流程分析
Feb 04 PHP
采集邮箱的php代码(抓取网页中的邮箱地址)
Jul 17 PHP
PHP 转义使用详解
Jul 15 PHP
php根据isbn书号查询amazon网站上的图书信息的示例
Feb 13 PHP
PHP根据两点间的经纬度计算距离
Oct 31 PHP
php生成不重复随机数、数组的4种方法分享
Mar 30 PHP
php+ajax无刷新分页实例详解
Dec 07 PHP
PHP flush 函数使用注意事项
Aug 26 PHP
PHP那些琐碎的知识点(整理)
May 20 PHP
使用PHP实现阻止用户上传成人照片或者裸照
Dec 25 #PHP
浅析PHP文件下载原理
Dec 25 #PHP
php使用sql server验证连接数据库的方法
Dec 25 #PHP
php实现mysql事务处理的方法
Dec 25 #PHP
php使用pdo连接mssql server数据库实例
Dec 25 #PHP
php连接与操作PostgreSQL数据库的方法
Dec 25 #PHP
完整删除ecshop中获取店铺信息的API
Dec 24 #PHP
You might like
使用array mutisort 实现按某字段对数据排序
2013/06/18 PHP
Drupal7连接多个数据库及常见问题解决
2014/03/02 PHP
php的laravel框架快速集成微信登录的方法
2016/12/12 PHP
基于Laravel实现的用户动态模块开发
2017/09/21 PHP
PHP基于递归算法解决兔子生兔子问题
2018/05/11 PHP
PHP多进程简单实例小结
2019/11/09 PHP
解决js中window.open弹出的是上次的缓存页面问题
2013/12/29 Javascript
javascript关于open.window子页面执行完成后刷新父页面的问题分析
2015/04/27 Javascript
jquery衣服颜色选取插件效果代码分享
2015/08/28 Javascript
js实现文字闪烁特效的方法
2015/12/17 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
2016/10/10 Javascript
mpvue 如何使用腾讯视频插件的方法
2018/07/16 Javascript
JavaScript实现选项卡效果的分析及步骤
2019/04/16 Javascript
ES6对象操作实例详解
2020/05/23 Javascript
举例详解Python中的split()函数的使用方法
2015/04/07 Python
Python实现的Google IP 可用性检测脚本
2015/04/23 Python
python去除文件中空格、Tab及回车的方法
2016/04/12 Python
Python xlwt设置excel单元格字体及格式
2020/04/18 Python
python爬虫爬取淘宝商品信息
2018/02/23 Python
python实现电脑自动关机
2018/06/20 Python
python处理multipart/form-data的请求方法
2018/12/26 Python
Python设计模式之适配器模式原理与用法详解
2019/01/15 Python
Python 读取 YUV(NV12) 视频文件实例
2019/12/09 Python
利用Python制作动态排名图的实现代码
2020/04/09 Python
对Matlab中共轭、转置和共轭装置的区别说明
2020/05/11 Python
Python 中的函数装饰器和闭包详解
2021/02/06 Python
旧时光糖果:Old Time Candy
2018/02/05 全球购物
美国最大的半成品净菜电商:Blue Apron(蓝围裙)
2018/04/27 全球购物
考试退步检讨书
2014/01/15 职场文书
教堂婚礼主持词
2014/03/14 职场文书
伊索寓言教学反思
2014/05/01 职场文书
金融专业毕业生自荐信
2014/06/26 职场文书
2014民事授权委托书范本
2014/09/29 职场文书
教师节慰问信
2015/02/15 职场文书
保护动物的宣传语
2015/07/13 职场文书
Win10 heic文件怎么打开 ? Win10 heic文件打开教程
2022/04/06 数码科技