首页 >php教程 >PHP源码 >PHP PDO操作mysql不注意的话依然存在SQL注入

PHP PDO操作mysql不注意的话依然存在SQL注入

PHP中文网
PHP中文网原创
2016-05-23 16:38:271522浏览

最近出了一本书叫做《代码审计:企业级web代码安全架构》,专门介绍怎么从代码里挖掘漏洞,漏洞应该怎么防御,功能应该怎么设计会更安全。 需要的朋友可以在淘宝、京东等网站搜索。

我们先来看一段代码

41be68adc98f27e9e15e6536364c7f29exec("set names 'gbk'");
$sql="select * from test where name = ? and password = ?";
$stmt = $dbh->prepare($sql);
$exeres = $stmt->execute(array($name, $pass));

上面这段代码虽然使用了pdo的prepare方式来处理sql查询,但是当PHP版本<5.3.6之前还是存在宽字节SQL注入漏洞,原因在于这样的查询方式是使用了PHP本地模拟prepare,再把完整的SQL语句发送给MySQL服务器,并且有使用set names 'gbk'语句,所以会有PHP和MySQL编码不一致的原因导致SQL注入,正确的写法应该是使用ATTR_EMULATE_PREPARES 来禁用PHP本地模拟prepare,代码如下:

41be68adc98f27e9e15e6536364c7f29setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
$dbh->exec("set names 'utf8'");
$sql="select * from test where name = ? and password = ?";
$stmt = $dbh->prepare($sql);
$exeres = $stmt->execute(array($name, $pass));

<?php 
dbh = new PDO("mysql:host=localhost; dbname=demo", "user", "pass");
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
$dbh->exec("set names &#39;utf8&#39;");
$sql="select * from test where name = ? and password = ?";
$stmt = $dbh->prepare($sql);
$exeres = $stmt->execute(array($name, $pass));


声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn