本文摘自PHP中文网,作者V,侵删。

前言
随着数据库参数化查询的方式越来越普遍,SQL注入漏洞较之于以前也大大减少,而PDO作为php中最典型的预编译查询方式,使用越来越广泛。
众所周知,PDO是php中防止SQL注入最好的方式,但并不是100%杜绝SQL注入的方式,关键还要看如何使用。
之前在一篇文章中了解到PDO场景下参数可控导致的多句执行等问题(https://xz.aliyun.com/t/3950)于是对PDO场景下的SQL注入又进行了一些探究。
PDO查询语句可控存在的安全问题:
首先在本地新建一个库和表,随便写点东西。

然后写一个test.php,用PDO进行简单的查询:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php
try {
$db = new PDO( 'mysql:host=localhost;dbname=pdotest' , 'root' , '' );
}
catch (Exception $e )
{ echo $e ->getMessage();
} if (isset( $_GET [ 'id' ]))
{
$id = $_GET [ 'id' ];
} else {
$id =1;
}
$query = "select balabala from table1 where 1=?" ; echo "id:" . $id . "</br>" ;
$row = $db ->prepare( $query );
$row ->bindParam(1, $id );
$row ->execute();
$result = $row ->fetch(PDO::FETCH_ASSOC); if ( $result )
{ echo "结果为:" ;
print_r( $result ); echo "</br>" ;
}
|
将输入的内容和得到的结果打印在页面上:

PDO与安全问题相关的主要的设置有下面三个:
1 2 3 | PDO::ATTR_EMULATE_PREPARES
PDO::ATTR_ERRMODE
PDO::MYSQL_ATTR_MULTI_STATEMENTS
|
分别与模拟预编译、报错和多句执行有关。
PDO默认是允许多句执行和模拟预编译的,在之前的很多文章中已经写到,在参数可控的情况下,会导致堆叠注入。
例如我们把查询语句改成:
1 2 | $query = "select balabala from table1 where 1={$id}" ;
$row = $db ->query( $query );
|
则在$db->query()这一步执行之前,我们便可以对$query进行非法操作,那PDO相当于没用:

PDO默认设置存在的安全隐患:
如果我们在查询语句中没有可控的参数,并把输入的参数按照prepare->bindParam->execute的方式去写就一定没有问题了吗?
我们按如下语句进行查询:
1 2 3 4 | $query = "select balabala from table1 where 1=?" ;
$row = $db ->prepare( $query );
$row ->bindParam(1, $_GET [‘id’]);
$row ->execute();
|
我们在URL中随便输入一个参数:?id=asdasd,然后通过设置SET GLOBAL GENERAL_LOG=ON,从.log里实时监控,看看sql语句到底执行了什么:
阅读剩余部分
相关阅读 >>
保护linux系统安全的方法介绍
linux下使用g++编译c++方法
tomcat中的startup.bat工作原理介绍
linux进入单用户模式的方法介绍
tomcat7.0.82在linux下安装的方法
tomcat中的catalina.bat工作原理介绍
mongodb的磁盘io问题的解决方法
学习linux步骤方法
linux下使用g++编译c++方法
linux下设置网卡ip地址的方法
更多相关阅读请进入《pdo》频道 >>
转载请注明出处:木庄网络博客 » PDO原理及正确使用方法