PDO原理及正确使用方法


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

前言

随着数据库参数化查询的方式越来越普遍,SQL注入漏洞较之于以前也大大减少,而PDO作为php中最典型的预编译查询方式,使用越来越广泛。

众所周知,PDO是php中防止SQL注入最好的方式,但并不是100%杜绝SQL注入的方式,关键还要看如何使用。

之前在一篇文章中了解到PDO场景下参数可控导致的多句执行等问题(https://xz.aliyun.com/t/3950)于是对PDO场景下的SQL注入又进行了一些探究。

PDO查询语句可控存在的安全问题:

首先在本地新建一个库和表,随便写点东西。

1.jpg

然后写一个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>";

}

将输入的内容和得到的结果打印在页面上:

32b816b79f148ba849ab804acc67b16.png

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相当于没用:

9f5fdf6b85204f167dd37d28aaf7b4d.png

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》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...