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

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

PHP中文网
PHP中文网asal
2016-05-23 16:38:271598semak imbas

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

我们先来看一段代码

4090a74e0a08aa0e0eaf507d52c0f85aexec("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,代码如下:

4090a74e0a08aa0e0eaf507d52c0f85asetAttribute(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));


Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:jiajiao网前后台Artikel seterusnya:git 使用测试代码