【问题标题】:Safety/vulnerability of using Codeigniter query builder custom where string使用 Codeigniter 查询生成器自定义 where 字符串的安全性/漏洞
【发布时间】:2018-05-04 19:53:54
【问题描述】:

我正在开发一个无法升级到 v.3 的 Codeigniter 2 项目。到目前为止,我在使用查询生成器时遇到了两难境地,尤其是当我需要进行更复杂的查询时。 CI v.3 通过使用 ->group_start() 和 ->group_end() 可以很好地处理它,但 CI v.2 没有。 现在,我的困境如下:仅使用自定义 where 查询是否安全?

$this->db->where("name='$name' AND status='boss' OR status='active'");

查询生成器是否对其进行了足够的清理,或者我应该使用额外的清理(第三个参数保留为默认值 - true)?

** 更新 **

我没有准确地写出我需要这个复杂的查询。沿着这个逻辑的某个地方:

A=1 && B=2 && C=3 && (D=10 || E=20 || F=30)

【问题讨论】:

    标签: php mysql codeigniter sanitization


    【解决方案1】:

    来自文档,https://codeigniter.com/userguide2/database/active_record.html#select

    注意:传递给此函数的所有值都会自动转义, 产生更安全的查询。

    我假设这是如果您正确使用它而不是像您的想法那样直接插入变量。

    所以我会这样做(如果我使用 CI :/)

    $this->db->where('name', $name);
    $this->db->where("(status='boss' OR status='active')", NULL, FALSE);
    

    ..丑

    【讨论】:

    • 但是,它不会产生类似以下的查询:...WHERE name = 'JOE' OR status = 'boss' OR status = 'active';我忘了提及为什么我需要这个 - 用于复杂的查询(不仅仅是像上面那样简单)。如果我需要得到这样的东西:(A&B)|| (C & D)。
    • @agapetos 已更新,有一些方法可以集成任何复杂的查询,但这只是意味着将您的正常查询分解到查询构建器中需要更长的时间。我喜欢RedBean,它太容易了。
    • 我同意它看起来很难看,但我仍然认为自定义 where() 函数仍然比 query() 更安全(因为,我猜,在 where() 函数中你不能做任何事情除了选择之外的其他)。还有一些其他解决方案需要使用 FALSE 作为第三个参数,但如果有其他选项,我选择不使用它。我也不知道使用 FALSE 作为第三个参数 + $this->db->e​​scape() 是否比自定义 where() 函数更安全。
    【解决方案2】:

    我使用 CI,但跳过了他们的查询生成器并使用 PDO。您仍然可以将所有设置放在/config/database.php 中并直接使用它们。

     class SomeModel_model extends CI_Model {
    
       protected $pdo;
    
       public function __construct() {
       parent::__construct();
    
       $this->load->database();
    
       $opt = array(
       PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
       PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
       );
    
       $this->pdo = new PDO($this->db->dsn, $this->db->username, $this->db->password, $opt);
    
       }
    

    然后选择...

      // $this->db->where("name='$name' AND status='boss' OR status='active'");
    
      $sql = "SELECT * from myTable where name = :name and (status = 'boss' OR status = 'active')';
    
      $stmt = $this->pdo->prepare($sql);
    
      $stmt->execute(['name' => $name]);
    
      $results = $stmt->fetch();
    

    【讨论】:

    • 这更像是一个建议,而不是他的问题的答案。
    【解决方案3】:

    您的查询的正确实现是

    $this->db
        ->where('name',$name)
        ->group_start()
            ->where('status','boss')
            ->or_where('status','active')
        ->group_end();
    

    编辑 Codeigniter 2

    $this->db
        ->where('name',$name)
        ->where('(status','boss')
        ->or_where('status',$this->db->escape('active').')',false);
    

    【讨论】:

    • “group_start()”和“group_end()”是第 3 版中的一个很好的更新,但正如我所指出的 - 我正在使用第 2 版,升级到第 3 版。
    • 我现在为版本 2 添加了一个可能的解决方案
    • 这对我查看查询构建器的方式提出了很大的挑战(将开始括号放在一行中,将结束括号放在另一行中),我已经对其进行了测试,它的工作方式与您描述的一样会。
    【解决方案4】:

    查询生成器只转义直接传递给它的数据,而不是通过字符串中的赋值。

    如果您想安全起见,只需在输入变量之前将其转义即可:

    $var1 = $this->db->escape_str($data)

    现在您的查询相对安全。

    Documentation of this here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多