Codeigniter:update_batch 未转义字段名称

发布于 2025-01-02 09:21:43 字数 1282 浏览 0 评论 0原文

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

I am trying to use the update_batch() function from the Active Record helper in Codeigniter as follows:

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

This prints out the following:

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')

Obviously, this is a large security hole because the field and table names are not being escaped from the update_batch section (although they are escaped in the where section). Am I doing something wrong? This behaviour is not specified in the docs:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄居人 2025-01-09 09:21:43

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

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

,我认为这意味着字段和表名不受保护。

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

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

$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>

Uhm, according to the documentation for the update_batch() function, they just claim that

"values are automatically escaped producing safer queries"

with these words, I see implied that fields and table names are not protected.

But in the "queries" page, they kind of contradict by saying:

In many databases it is advisable to protect table and field names -
for example with backticks in MySQL. Active Record queries are
automatically protected, however if you need to manually protect an
identifier you can use:

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

And IIRC it's true, AR always wraps names in backticks (that's why you need to pass FALSE, usually, to the active record method if you don't want escaping to mess with your query part).

EDIT:

Uhm, I just went rapidly over the code, and it looks like it is escaped:

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

So, migth really be a bug; So far, if your table names aren't dynamically generated, you can simply ignore this and be safe anyway; or you could run the protect_identifiers() method and do that yourself (wrong in principle, but hey...).

You can try and reproduce the bug more than once, and then file a bug report

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文