网站广播 本站提供的源码经过测试有前台及后台管理界面演示图免费下载
php中防止SQL注入的最佳解决方法
2014-11-14 08:33:47      浏览:
本篇文章介绍了php中防止SQL注入的最佳解决方法需要的朋友参考下

如果用户输入的是直接插入到一个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;'


我们应该怎么防止这种情况呢?下面我们来看看Theo的回答

 

使用预备义语句和参数化查询对于带有任何参数的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脚本包括恶意字符串发送到数据库.因此通过发送?#23548;?#30340;分开的sql参数,你会降低风险.使用准备好的语句时你发送的任何参数将只被?#28216;?#23383;符串虽然数据库引擎可能会做一些参数的优化当然最终可能会为数字.在上面的例子中如果变量$name包含'sarah';DELETE * FROM employees,结果只会是一个搜索的字符串"'sarah';DELETE * FROM employees",你不会得到一个空表

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

复制代码代码如下:

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


Tagsphp中防止SQL注入的最佳解决方法
打印 繁体关闭 返回顶部
上一篇php怎么调用远程数据实现代码 下一篇phpStudy2013开启gd库 解决方法

广告推荐

PHP技术文章推荐阅读

190aa.com ߱ȷ