【问题标题】:Codeigniter: update_batch not escaping field namesCodeigniter:update_batch 不转义字段名称
【发布时间】:2012-02-04 09:05:40
【问题描述】:

我正在尝试使用 Codeigniter 中 Active Record 助手中的 update_batch() 函数,如下所示:

var_dump($data);
$this->db->where('event_id',$data['event_id']);
$this->db->update_batch('results',$data['results'],'uid');
echo $this->db->last_query();

这会打印出以下内容:

array(2) {
  ["event_id"]=>
  string(2) "11"
  ["results"]=>
  array(2) {
    [0]=>
    array(2) {
      ["uid"]=>
      string(36) "1beab26d-f705-11e0-a190-f46d048dfd25"
      ["res"]=>
      string(1) "2"
    }
    [1]=>
    array(2) {
      ["uid"]=>
      string(36) "9dcc9e0a-bf24-11e0-838c-f46d048dfd25"
      ["res"]=>
      string(1) "1"
    }
  }
}
UPDATE results SET res = CASE 
WHEN uid = '1beab26d-f705-11e0-a190-f46d048dfd25' THEN '2'
WHEN uid = '9dcc9e0a-bf24-11e0-838c-f46d048dfd25' THEN '1'
ELSE res END WHERE `event_id` = '11' AND uid IN ('1beab26d-f705-11e0-a190-f46d048dfd25','9dcc9e0a-bf24-11e0-838c-f46d048dfd25')

显然,这是一个很大的安全漏洞,因为字段和表名没有从update_batch 部分转义(尽管它们在where 部分中转义)。难道我做错了什么?文档中未指定此行为:

http://codeigniter.com/user_guide/database/active_record.html#update

【问题讨论】:

  • 实际上看起来像一个错误/疏忽,但除非您动态传递表名,否则我看不出不转义它们会造成麻烦。您能否举一个可能导致安全问题的示例?
  • $data 来自用户输入,不可信。
  • 啊,'res' 和 'uid' 作为数据传入,这是一个安全问题... :-/

标签: php sql codeigniter escaping


【解决方案1】:

嗯,根据 update_batch() 函数的文档,他们只是声称

“值会自动转义以产生更安全的查询”

我看到这些词暗示字段和表名不受保护。

但是在“查询”页面中,他们说的有点矛盾:

在许多数据库中,建议保护表名和字段名 - 例如 MySQL 中的反引号。 Active Record 查询是 自动保护,但是如果您需要手动保护 您可以使用的标识符:

$this->db->protect_identifiers('table_name');

IIRC 确实如此,AR 总是将名称包含在反引号中(这就是为什么如果您不想转义弄乱查询部分,通常需要将 FALSE 传递给活动记录方法)。

编辑:

嗯,我刚刚快速浏览了代码,看起来被转义了

// Batch this baby
for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
{
   $sql = $this->_update_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->ar_set, $i, 100), $this->_protect_identifiers($index), $this->ar_where);

   $this->query($sql);
}

所以,可能真的是一个错误;到目前为止,如果您的表名不是动态生成的,您可以简单地忽略它并且无论如何都是安全的;或者您可以运行 protect_identifiers() 方法并自己执行此操作(原则上是错误的,但是嘿...)。

您可以多次尝试重现该错误,然后提交a bug report

【讨论】:

  • $data 数组是从 ajax 查询中发送的。所以输入不能被认为是安全的。另外,示例中的用法有用反引号转义的字段。也许这真的是一个错误。
  • 是的,他们应该反引号,真的。顺便说一句,您使用的是什么数据库驱动程序?我没有看到这方面的错误报告(不过只是略过列表),可能在错误跟踪器上提交一份
猜你喜欢
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
相关资源
最近更新 更多