它假设一个带有多个绑定的更复杂的查询,所以请不要指导我使用像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注入?
答案 0 :(得分:0)
据我所知,文档here和here,ANY
会将您传递的字符串转换为数组,然后使用operator
({{1} })比较数组中每个匹配的值。
在这种情况下,我认为pgsql做了一点:它已经看到=
(lvalue
)是整数类型,所以它期望一个整数数组。由于id
不是整数,所以你有这个。
您应该检查3+
数组的内容(使用filter_var等)以确保您只有整数值。
由于您明确希望查询以非预期的结果运行,因此这会作为正确的SQL注入失败,因为ids
检查其输入并且查询在运行之前失败。
但是,如果pgsql附带了一个从范围构建整数数组的工具,比如ANY
,那么你可能会遇到问题,因为查询将匹配更多的行。