Yii2中如果你这么写,可能造成sql注入漏洞

使用Yii2.0有一段时间了,说下写法不当可能会引发的sql注入问题吧。为什么使用Yii2.0,优缺点就先不说了,主要是公司目前统一使用这个PHP框架。

$id = Yii::$app->request->get('id','');//get获取参数


1.1 直接把获取的$id代入(有问题)

$sql     = "SELECT * FROM   tab WHERE id = {$id}";
$db      = \Yii::$app->db;
$command = $db->createCommand($sql);//存在注入漏洞,方法内部并未对$id进行过滤或其它处理
$result  = $command->queryAll();
var_dump($result);


1.2 增加一个参数,Yii内部方法会将其参数化

$sql     = "SELECT * FROM   tab WHERE id = :id";
$db      = \Yii::$app->db;
$command = $db->createCommand($sql, [':id' => $id]);//方法内部对第二个参数进行PDO参数化,不会导致注入漏洞
$result  = $command->queryAll();
var_dump($result);

[':id' => $id] 是数组的简写(php5.4+支持,Yii2也需要php5.4+才支持),等同于array(':id' => $id)



2.1 直接把获取的$id代入(有问题)

//Tab是Model,与数据库中的Tab表对应
$result = Tab::findAll("id={$id}");//参数为字符串,方法内部不会进行过滤,导致注入漏洞
var_dump($result);


2.2 参数为数组的写法,Yii内部方法会将其参数化

$result = Tab::findAll(['id' => $id]);//参数为数组,方法内部调用PDO进行参数化,不会导致注入漏洞
var_dump($result);


以上有导致漏洞的写法是由于没有对用户输入的$id进行过滤,编写代码的人又没对输入的数据进行处理(Yii2 的GET POST REQUEST等不过滤用户输入的数据。论坛上有人问过Yii的作者为什么不过滤,作者说是为了防止把“好”数据过滤掉)


自己写过滤方法防止sql注入早已过时,一般都采用参数化的方式,PDO((PHP Data Object)支持参数化,php5.1+就能支持PDO连接MySql。其它语言如.net中也都是推荐使用参数化而不是拼接sql的方式。


所以并不是使用框架就不会导致sql注入或者XSS等,一是要看你使用什么框架,一是写法要符合规则才能使其中的安全机制起作用。


BTW,Yii2中,对输出的数据也要调用其方法html::encode()或php自身的函数htmlspecialchars()或htmlenocde()进行编码或过滤防止XSS。


类别:PHP   阅读(0)   评论(0)    发表时间:2015-09-16 22:06  星期三

评论区

发表评论

        姓名:
邮箱|网站:
        内容:

  (可按Ctrl+Enter提交)