Codeigniter:update_batch不转义字段名称

时间:2012-02-04 09:05:40

标签: php sql codeigniter escaping

我正在尝试使用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部分中被转义)。难道我做错了什么?在docs中未指定此行为:

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

1 个答案:

答案 0 :(得分:1)

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

  

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

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

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

  

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

     

$这 - > DB-> protect_identifiers( '表名');

而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);
}

所以,migth真的是一个bug;到目前为止,如果您的表名不是动态生成的,您可以简单地忽略它并保持安全;或者你可以运行protect_identifiers()方法自己做(原则上是错的,但是嘿......)。

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