如何注入这个 sql 查询?

How can this sql query be injected?

我有一个 php 代码,我从 GET 请求中获取页码,然后 运行 通过 sql 查询数据库中的 select 记录页码

$maxPerPage = 20;

$page = $_GET["p"];

$applicants = DB::query('SELECT * FROM registrees ORDER BY id DESC LIMIT 
'.$page*$maxPerPage.','.$maxPerPage);

我的问题是有人可以在此代码中注入 SQL 查询吗?如果它可能发生,我需要 sql-注入的例子,可以 运行 这里。

在这种情况下,PHP 拯救了您,而不是 SQL。

https://wiki.php.net/rfc/invalid_strings_in_arithmetic 解释 Notice: A non well formed numeric value encountered 通知。 PHP 7.1 引入更严格 关于在算术表达式中使用字符串的规则。

您的表达式 $page*$maxPerPage 是一个算术表达式,但您正试图将字符串 $page 乘以一个整数。这会引起通知。

您可以通过不启用 error_reporting(E_NOTICE); 或使用 @ 运算符抑制通知来忽略通知:

@$numberOfApples = "10 apples" + "5 apples";

无论您是否取消通知,该值都将转换为数字,忽略数字后的额外文本。这发生在乘法结果被插入到你的 SQL 字符串之前,所以它保证是一个整数,因此它是安全的 SQL 注入。

另一种解决方法是在从 $_GET 超全局变量中获取它时将 $page 强制为整数:

$page = (int) $_GET["p"];

一旦你这样做了,你就可以在你的乘法中使用它而不会引起注意。但是通过将其转换为整数,您已经过滤掉了可能导致 SQL 注入的所有内容。

所以上面的评论无法提供一个 SQL 注入利用的例子,因为在这个例子中有 none 可能。

但使用查询参数而不是连接字符串仍然是一个好习惯。原因是,如果你使用不同的方法,就需要程序员深入理解表达式在每种情况下的计算方式。如果他们看到像您这样的字符串连接表达式,他们当然会注意到它是一个潜在的 SQL 注入漏洞,并且需要一些时间来分析它,直到他们明白它是安全的。

您想使后继者易于维护您的代码。这意味着要明确和一致。毫无疑问,在某些情况下,您必须使用查询参数,因为您要插入字符串,而不是算术表达式的结果。任何阅读您的代码的程序员都会想知道,"why use query parameters only sometimes?"

所以我同意其他评论,您应该使用查询参数,而不是字符串连接,即使您知道 PHP 表达式的一些细微差别在特定情况下是安全的。

使用mysqli_real_escape_string($connection, $_GET[“p”]);以确保输入。