如果所有SQL查询都应该准备好以防止SQL注入,为什么语法允许未准备好的查询



既然所有SQL查询都应该准备好以防止SQL注入,为什么我们允许编写和执行未准备好的查询?这不是违反直觉吗?

在查询是固定字符串并且不需要任何程序变量的情况下,使用query()运行它是安全的。

以下是中的示例https://www.php.net/manual/en/pdo.query.php:

<?php
$sql = 'SELECT name, color, calories FROM fruit ORDER BY name';
foreach ($conn->query($sql) as $row) {
print $row['name'] . "t";
print $row['color'] . "t";
print $row['calories'] . "n";
}

查询中没有PHP变量。query()就足够了,并且实现了与prepare()execute()相同的功能。

如果您需要用PHP变量替换SQL表达式中的值,那么您可以使用参数:

$sql = 'SELECT name, colour, calories FROM fruit
WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql);
$sth->execute(array('calories' => 150, 'colour' => 'red'));

您可能会发现,这在应用程序中比运行固定查询更常见。

即使您需要使用prepared语句,也无法阻止通过变量替换创建prepared声明。例如

$sql = "SELECT * FROM someTable WHERE id = $id";
$stmt = $conn->prepare($sql);

绑定参数和查询准备是两回事。你可以做其中一个或另一个,也可以两者兼而有之。

您需要绑定参数以防止SQL注入。但是,有些东西不能作为参数传递(例如ORDER BY列表(,在这种情况下,您可以将所需的SQL语法直接连接到SQL字符串中。这被称为"动态SQL",通常应该只使用白名单字符串来防止SQL注入。

因此,为了回答(我认为是(您的问题:允许动态SQL,因为有些情况不在绑定参数的范围内。

相关内容

最新更新