它假定了一个具有多个绑定(bind)的更复杂的查询,所以请不要指导我在这个例子中使用 implode(',',$ids), (?,?,?) 或 PDO 可能性。
问题是要阐明这种特定方法的 SQL 注入(inject)的可能性。
url中有参数1,2,3 http://localhost/executeSql/1,2,3 . 该参数通过绑定(bind)到 = 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 注入(inject)的适当保护?
最佳答案
据我从文档中了解到 here和 here , ANY
将您传递的字符串转换为数组,然后使用 operator
(=
) 比较数组中的每个值匹配。
在这种情况下,我认为 pgsql 做的更多一些:它已经看到 lvalue
(id
) 是整数类型,所以它需要一个整数数组。因为 3+
不是整数,所以你有这个。
您可能应该检查 ids
数组的内容(使用 filter_var 等)以确保只有整数值。
由于您明确希望查询以意外结果运行,因此作为正确的 SQL 注入(inject)失败,因为 ANY
检查其输入并且查询在运行前失败。
但是,如果 pgsql 带有从范围构建整数数组的功能,如 {1:999999999999}
,那么您可能会遇到问题,因为查询将匹配更多的行。
关于php - 将数组绑定(bind)到 =ANY() 条件的 SQL 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32166806/