标签:
原文:php安全编程—sql注入攻击根据相关技术原理,SQL注入可以分为平台层注入和代码层注入。前者由不安全的数据库配置或数据库平台的漏洞所致;后者主要是由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。基于此,SQL注入的产生原因通常表现在以下几方面:
在某些表单中,用户输入的内容直接用来构造动态sql命令,或者作为存储过程的输入参数,这些表单特别容易受到sql注入的攻击。而许多网站程序在编写时,没有对用户输入的合法性进行判断或者程序中本身的变量处理不当,使应用程序存在安全隐患。这样,用户就可以提交一段数据库查询的代码,根据程序返回的结果,获得一些敏感的信息或者控制整个服务器,于是sql注入就发生了
强制字符格式(类型)
SELECT * FROM article WHERE articleid=‘$id‘
使用pdo 使用 prepared statements ( 预处理语句 )和参数化的查询。这些SQL语句被发送到数据库服务器,它的参数全都会被单独解析。使用这种方式,攻击者想注入恶意的SQL是不可能的
使用PDO访问MySQL数据库时,真正的real prepared statements 默认情况下是不使用的。为了解决这个问题,你必须禁用 prepared statements的仿真效果。下面是使用PDO创建链接的例子:
<?php
$dbh = new PDO('mysql:dbname=mydb;host=127.0.0.1;charset=utf8', 'root', 'pass');
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
?>
这可以确保SQL语句和相应的值在传递到mysql服务器之前是不会被PHP解析的(禁止了所有可能的恶意SQL注入攻击)
完整示例代码:
<?php
$dbh = new PDO("mysql:host=localhost; dbname=mydb", "root", "pass");
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //禁用prepared statements的仿真效果
$dbh->exec("set names 'utf8'");
$sql="select * from table where username = ? and password = ?";
$query = $dbh->prepare($sql);
$exeres = $query->execute(array($username, $pass));
if ($exeres) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
print_r($row);
}
}
$dbh = null;
?>
当调用 prepare() 时,查询语句已经发送给了数据库服务器,此时只有占位符 ? 发送过去,没有用户提交的数据;当调用到 execute()时,用户提交过来的值才会传送给数据库,它们是分开传送的,两者独立的,SQL攻击者没有一点机会。如下几种情况,pdo prepared statements 将不能起到防范的作用
select * from table where userid in ( ? );
$ids = ‘1,2,3,4,5,6‘; select * from table where find_in_set(userid, ?);
select * from table order by ?;
select extract( ? from addtime) as mytime from table;
标签:
原文地址:http://www.cnblogs.com/lonelyxmas/p/4193506.html