我有一个php代码,我从GET请求中获取页码,然后运行sql查询以按页码从数据库中选择记录。
$maxPerPage = 20;
$page = $_GET["p"];
$applicants = DB::query('SELECT * FROM registrees ORDER BY id DESC LIMIT
'.$page*$maxPerPage.','.$maxPerPage);
我的问题是有人可以在此代码中插入SQL查询吗?如果可能发生,我需要可以在此处运行的sql-injection示例。
在这种情况下,您是通过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注入。
另一个解决方法是,当您从$page
超全局变量中获取$_GET
时,将其强制为整数:
$page = (int) $_GET["p"];
一旦执行此操作,就可以在乘法中使用它而不会引起通知。但是通过将其强制转换为整数,您已经过滤掉了可能导致SQL注入的所有内容。
因此,以上注释无法提供SQL注入攻击的示例,因为此示例中不可能。
但是使用查询参数而不是连接字符串仍然是一个好习惯。原因是,如果使用不同的方法,则要求程序员深入了解表达式在每种情况下的计算结果。如果他们看到像您这样的字符串连接表达式,他们当然会注意到它是潜在的SQL注入漏洞,并且需要一段时间来对其进行分析,直到他们了解它是安全的为止。
您想让您之后的人易于维护您的代码。那意味着要清楚和一致。毫无疑问,在某些情况下,您必须使用查询参数,因为您要插入字符串,而不是算术表达式的结果。任何阅读您的代码的程序员都会怀疑,“为什么有时只使用查询参数?”
因此,我同意其他注释,即使您由于某些PHP表达式的细微差别而知道在特定情况下也是安全的,您应该使用查询参数,而不是字符串连接。