如果我确定我在动态语句中使用的某个值是整数,我可以避免 SQL 注入吗?

Am i safe from SQL injection if i know for sure that a certain value i am using in a dynamic statement is an integer?

在进行查询之前,我使用以下代码检查要在该查询中使用的变量是否为整数:filter_var($_POST["user_id"], FILTER_VALIDATE_INT) !== false

我的问题是,如果上述函数 returns 只有当我的值为整数时才为真(这意味着我要用来构建查询的值是安全的),我应该使用 PDO 还是进行任何转义?如果我的值已经通过了上述测试,是否还需要使用准备好的语句对值进行转义?

我没有对上面的内容进行过任何测试,也没有真正的服务器端技术经验,所以请 PHP/security 专家指导我。

使用准备好的语句仍然是个好主意。此时的绑定函数是经过验证的。

  1. 如果您或其他人搞砸了过滤器怎么办?

  2. 您会记得在代码中的每个点都使用正确的过滤器吗?这是一件很容易管理不善的事情,有时您可能无法为所有可能发生的情况做好计划。整数相对容易,但字符串要复杂得多。

  3. 关于你的专业声誉,其他人会看到这段代码吗?如果你有开源代码(比如 github 之类的),而我是一名正在调查你的历史的招聘经理,我不会因为你违反了像这样的标准安全实践而雇用你。

诚然,第3点有点跑题,但我觉得值得一提。

也许您需要在使用前查看 php 错误页面 this 页面 FILTER_VALIDATE_INT

This answer is an explanation of the shorthand type casting, from comments, as it's easier to read it as an answer than as a set of comments.

您的代码:

filter_var($_POST["user_id"], FILTER_VALIDATE_INT) !== false. 

这是确保 POSTed 数据为整数的冗长方法。它有问题,因为 POST 数据 总是转换为字符串

 $_POST["user_id"] = (int)$_POST["user_id"]; 

更易于阅读且输入更短,这 强制 数据为 整数 类型。如果将非整数数据放入 SQL 中的整数位置,这将完全解决您的安全风险。

这 utalises PHP Type Juggling 值得一读。

虽然上面的代码将解决您的安全问题,但它会引发其他重叠问题,因为任何字符串都可以转换为整数,但如果字符串不以 an 开头,则转换为 return 0整数值。

示例:

$string = "hello";
print (int)$string; // outputs 0;

$string = "27hello";
print (int)$string; // outputs 27;

$string = true;
print (int)$string; // outputs 1;

$string = "";
print (int)$string; // outputs 0;

因此,总的来说,我建议使用以下行来确保您给定的 POST 值是正确的整数:

if (strcmp((int)$_POST['value'], $_POST['value']) == 0){
    /// it's ok!
}

请参阅this answer for further details as well as this PHP manual page