将数组绑定到= ANY()条件的SQL注入

时间:2015-08-23 12:47:22

标签: php postgresql laravel pdo

它假设一个带有多个绑定的更复杂的查询,所以请不要指导我使用像implode(',',$ ids),(?,?,?)或PDO可能性这样的例子。

问题是要澄清这种特定方法的SQL注入的可能性。

网址http://localhost/executeSql/1,2,3中有参数1,2,3。 该参数通过绑定到= ANY运算符作为PostgreSQL 9.3的数组“{1,2,3}”的字符串表示形式传递。

Laravel 5.1上的php代码:

public function executeSql($ids)
{
    $ids='{'.$ids.'}';
    $condition = 'WHERE id = ANY(:ids)';
    $sql="SELECT id FROM (VALUES (1),(2),(3)) AS t(id) $condition";
    DB::select($sql,[':ids'=>$ids]);
}

结果是查询: SELECT id FROM(VALUES(1),(2),(3))AS t(id)WHERE id = ANY('{1,2,3}')

这很有效,直到参数只包含整数。 如果参数是1,2,3+,则发生QueryException:

无效的文本表示:7错误:整数的输入语法无效:“3 +”

是否可以将其视为适当的保护以避免SQL注入?

1 个答案:

答案 0 :(得分:0)

据我所知,文档herehereANY会将您传递的字符串转换为数组,然后使用operator({{1} })比较数组中每个匹配的值。

在这种情况下,我认为pgsql做了一点:它已经看到=lvalue)是整数类型,所以它期望一个整数数组。由于id不是整数,所以你有这个。

您应该检查3+数组的内容(使用filter_var等)以确保您只有整数值。

由于您明确希望查询以非预期的结果运行,因此这会作为正确的SQL注入失败,因为ids检查其输入并且查询在运行之前失败。

但是,如果pgsql附带了一个从范围构建整数数组的工具,比如ANY,那么你可能会遇到问题,因为查询将匹配更多的行。