|
1
|
$id
= Yii::$app->request->get('id','');//get获取参数 |
1.1 直接把获取的$id代入(有问题)
|
1
2
3
4
5
|
$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内部方法会将其参数化
|
1
2
3
4
5
|
$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代入(有问题)
|
1
2
3
|
//Tab是Model,与数据库中的Tab表对应$result
= Tab::findAll("id={$id}");//参数为字符串,方法内部不会进行过滤,导致注入漏洞var_dump($result); |
2.2 参数为数组的写法,Yii内部方法会将其参数化
|
1
2
|
$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。
------------参数化的模糊查询------------------------------------------
使用如下语句将导致错误:
- $books = \Yii::$app->db->createCommand("SELECT * FROM book1 where book_title like '%:keywords%' order by addtime desc")->bindValue(":keywords",$_GET['keywords'])->queryAll();
$books = \Yii::$app->db->createCommand("SELECT * FROM book1 where book_title like '%:keywords%' order by addtime desc")->bindValue(":keywords",$_GET['keywords'])->queryAll();实际执行的语句为
可以看到经过该函数防sql注入处理之后的 $_GET['keywords'] ,自动为上传的关键字加上了单引号,导致执行的SQL语句无法正常查询出来结果,无法把数据库存在的《算法》 查询出来。
经过查询资料,更换了以下的接口函数,可以既实现模糊查询,又可以实现防SQL注入。
$db = new \yii\db\Query;
- $books= $db->from('book1')->where("book_title like :keywords")->addParams([':keywords'=>'%'.$_GET['keywords'].'%'])->orderBy('addtime DESC')->all();
$books= $db->from('book1')->where("book_title like :keywords")->addParams([':keywords'=>'%'.$_GET['keywords'].'%'])->orderBy('addtime DESC')->all();
本文探讨了在Yii2框架中如何避免SQL注入攻击。通过对比不同查询方式,阐述了参数化查询的重要性,并提供了安全实践建议。


429

被折叠的 条评论
为什么被折叠?



