php - 学说查询生成器 : SQL Injection risk in addOrderBy() method?

标签 php symfony doctrine-orm sql-injection

我在 Symfony 2.8 项目中使用 Doctrine,我想知道在使用 addOrderBy() 时是否存在 SQL 注入(inject)的风险queryBuilder 的方法:

// Order options. Real code does not specify this manually, but receives 
// the options via user form input
$orderBy' = array(
    'column1' => 'ASC',
    'column2' => 'DESC',
    ...
    'columnN' => 'ASC',
);

$qb = $this->em->createQueryBuilder();
...

foreach ($orderBy as $column => $orderOption) {
     $qb->addOrderBy("e.$column", $orderOption);

     // Does not work:
     // $qb->addOrderBy("e.$column", ':orderOption')
     //  ->setParameter('orderOption', $orderOption);
     // 
     // Error: Expected end of string, got ':orderOption'"
}

// Result is something like:
...ORDER BY e0_.column1 ASC, e0_.column2 DESC...

问题是,订单选项是通过用户表单输入接收的,可以像 这样操作; DROP TABLE someTable 而不是 ASCDESC

我已经试过了,但是查询生成器似乎不接受由 ; 分隔的多个查询,这并不意味着不可能有任何其他/更好的注入(inject):-)

当然,通过过滤接收到的结果并跳过所有无效的搜索选项,可以很容易地解决这个问题。但我想了解,如果 addOrderBy() 方法一般。 将任何值传递给方法是否省事,Doctrine 将处理其余部分,还是存在潜在风险?

我想知道为什么 ->setParameter() 方法不起作用,就像使用 ->where() 时一样。

最佳答案

简短的回答是,表单提交的列名实际上可以用于 sql 注入(inject)攻击。 Doctrine 假定您已正确验证列(和表)名称。

条令代码相当容易阅读,对于这类问题值得一看:

public function addOrderBy($sort, $order = null)
{
    $orderBy = ($sort instanceof Expr\OrderBy) ? $sort : new Expr\OrderBy($sort, $order);

    return $this->add('orderBy', $orderBy, true);
}

请注意,在您的查询中使用 Expr 没有任何值(value)。 Doctrine 负责为您生成它们。

$this->add 有点复杂,但基本上第二个参数最终被传递,没有转义或过滤等。

I wonder why the ->setParameter() method does not work, as it would when using ->where()

重要的概念是准备好的语句只保护而不是列名或表名。

因此,过滤来自野外的表/列名称完全取决于您。查看源代码可以提供信息。

关于php - 学说查询生成器 : SQL Injection risk in addOrderBy() method?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41019316/

相关文章:

php - 在当前目录中启动服务器 (php/apache)

javascript - 为什么 php 在打印数据时会在客户端断开连接时中止,但在其他情况下不会中止?

php - Symfony2 用户提供者必须在登录时返回一个 UserInterface 对象

php - 可捕获的 fatal error : Argument 1 passed to (. ..) 必须是给定的 (...) 整数的实例

emacs - symfony2 与 emacs 互锁文件的问题

mysql - 在 LiipFunctionalTest 包中使用 YEAR、MONTH、DAY mysql 函数时出错

php - 调用非对象的成员函数

php - 从手机上传的图片旋转90度? PHP

php - Doctrine 查询构建器,按年和月返回日期,忽略日期

symfony - 如何从 Controller 内部使用 Symfony 2.1 获取 Doctrine 实体的实体管理器