PHP MySQL 注入安全性:验证 $_GET 输入是否为数字是否提供了足够的保护?

PHP MySQL injection security: Does verifying that $_GET input is numeric provide enough protection?

我意识到我的应用程序的以下部分有可能被 MySQL 注入。

$id= $_GET['id'];
$query = "SELECT * FROM clients WHERE id = $id";
//run query

我在 运行 MySQL 查询之前检查 is_numeric($id) 是否足够安全?或者我是否有必要使用准备好的语句重写我的代码?

您应该使用准备好的语句,因为 mysql_* 函数已弃用。话虽这么说,一个数值将使 SQL 语句绝对安全,因为 SQL 注入要求变量实际上有 SQL 类似的语句。

例如 1;-

如果您没有时间使用准备好的语句重写查询,我会说我更有信心转换用户输入。

$id = (int) $_GET['id'];

由于此变量现在是 int,因此它不可能包含恶意输入。当然,您仍然应该对其进行任何必要的范围验证(例如,如果不允许使用负数)。

我假设此列是一个整数,但是 (float) 可以在这里以相同的方式使用,用于数字而非整数的数据。

为避免疑义,参数绑定仍然是将用户输入注入查询的最佳方法。我在这里的回答是为了直接回答问题的主旨,即有没有一种方法可以使查询安全而不具有约束力?上面的回答表明答案是肯定的

如果您将参数限制为整数,但您还想在服务器端验证参数,这将减少攻击面(不要将安全检查留在客户端,因为客户端可以绕过它们那些很容易)。

为了应用程序安全(尤其是 PHP 安全,因为它充满了安全问题),始终 考虑所有用户提供的数据都是一个好主意恶意的。因此,在允许应用程序对该数据进行操作和处理之前,仔细检查所有参数是否符合预期的标准。

您可以通过使用 PHP 准备好的 SQL 语句来帮自己一个忙,因为这些是一种添加机制(在您自己的验证之上),可以显着减少注入攻击面。

这里有一个资源可以让您更熟悉 PHP 准备好的语句:

http://php.net/manual/en/mysqli.quickstart.prepared-statements.php

这个想法是通过指定参数的数据类型来避免注入攻击,并为您构建更安全的查询字符串。但同样 - 在进一步处理之前始终检查 incoming/user-supplied 数据。