引自this SO answer :
Everything submitted is initially treated like a string, so forcing known-numeric data into being an integer or float makes sanitization fast and painless.
这是我独立提出的清理方法,用于快速而肮脏的查询(从数字 ID 查找表中的名称);插入查询的唯一变量是 ID,我知道 ID 应该大于零且小于 255,所以我的清理如下(也加入了一些验证):
$id = (int)$_REQUEST['id'];
if ($id < 1 || $id > 255) errmsg("Invalid ID specified!");
$name = $DB->query("SELECT name FROM items WHERE id=${id}")->fetch_all()[0][0];
这是否足以防止 SQL 注入(inject)攻击或任何其他基于用户指定的 $id
值的恶意攻击,还是它仍然可以被利用?
注意:ID/名称不是“敏感的”,因此如果某些输入无意中转换为“1”或其他有效的 ID 值,我不在乎。我只是想避免沿着 Little Bobby Tables 的滑稽 Action .
最佳答案
TL;DR 的答案是肯定的。当您转换为 (int)
时,您只能返回一个整数。
要注意的是,您可能有一个用例,在该用例中这会产生不良行为。让我们把你的代码
$id = (int)$_REQUEST['id'];
现在,如果我们调用它
page.php?id=lolsqlinjection
那么$id
的值为0
(因为字符串以字符开头,所以默认会强制转换为0
,见the PHP manual for various oddities with casting strings to integer)。因此,任何 SQL 注入(inject)都被删除,使其免受该攻击向量的影响。 但您可能有一个用例,其中 0
是一个特例,或者是另一条记录。这就是准备好的语句往往被认为更好的原因(显示 MySQLi,但您也可以使用 PDO 做到这一点)
$prep = $DB->prepare("SELECT name FROM items WHERE id=?");
$prep->bind_param('i', $_REQUEST['id']);
$prep->execute();
它的作用是告诉您的数据库您想要与输入匹配的记录。因此,通过我的 SQL 注入(inject),MySQL 现在正在寻找一个整数 ID 为“lolsqlinjection”的项目。不存在这样的记录。因此,我们避免了任何潜在的边缘情况,其中 0
将是一个有效的输入。
关于php - 将用户输入转换为足以对其进行清理的整数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48933793/