【问题标题】:How to generate ActiveQuery with client defined query string parameters safely in Yii2?如何在 Yii2 中安全地使用客户端定义的查询字符串参数生成 ActiveQuery?
【发布时间】:2018-10-08 17:51:10
【问题描述】:

有没有一种安全的方法来为 Yii2 ORM 生成带有 查询字符串 参数的条件子句? 例如,我们需要一些食品的列表,按属性过滤:

GET /food/?weight[>]=1000&calories=[<]=200

产品有很多不同的属性:重量、卡路里、数量、价格。

我希望可以写出类似(简化代码)的东西:

 $query = new \yii\db\Query();
 foreach ($_GET as $parameter => $condition){
    foreach ($condition as $operator => $value){
        $query->where(new SimpleCondition($parameter, $operator, $value));
    }
 }

但我怀疑这种方法安全

所以,有三个问题:

  1. 如何安全地从 url 定义属性?我们可以在ActiveQuery::where 子句中使用查询字符串参数names(而不是values)吗?
  2. 如何正确定义IN, AND, OR, &gt;, &lt;, &gt;=, &lt;=, etc.等运算符?
  3. 是否有任何用于过滤的原生 Yii2 组件或者我应该使用第三方模块?

【问题讨论】:

  • 这绝对不安全——这段代码易受 SQL 注入攻击。
  • @rob006 那么,正确的方法是什么?

标签: php yii2 query-string sql-injection


【解决方案1】:

最后,我找到了解决方案。 Yii2 似乎通过DataFilter 类提供了这样的功能。 类的官方documentation和使用它的guide

根据文档

  1. 定义验证模型。

    class SearchModel extends \yii\base\Model
    {
        public $id;
        public $name;
    
        public function rules()
        {
            return [
                [['id', 'name'], 'trim'],
                ['id', 'integer'],
                ['name', 'string'],
            ];
        }
    }
    
  2. 创建过滤器:

    $filter = new DataFilter(['searchModel' => $searchModel]);
    
  3. 用数据填充过滤器,验证

    if ($filter->load(\Yii::$app->request->get())) { 
       $filterCondition = $filter->build();
       if ($filterCondition === false) { // if error occure
           // the errors are stored in the filter instance
           return $filter;
       }
    }
    
  4. Query 过滤器中使用内置条件

    $query->andWhere($filterCondition);
    

【讨论】:

    猜你喜欢
    • 2020-12-18
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多