我正在尝试使用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
答案 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