如果所有 SQL 查询都应该准备好防止 SQL 注入,为什么语法允许非准备查询?
If all SQL queries should be prepared to prevent SQL injections, why does the syntax allow non-prepared queries?
既然所有SQL查询都应该准备好防止SQL注入,为什么我们允许编写和执行非准备查询?这看起来是不是违反直觉?
即使您需要使用准备语句,也无法阻止通过变量替换创建准备语句。例如
$sql = "SELECT * FROM someTable WHERE id = $id";
$stmt = $conn->prepare($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'));
您可能会发现这在您的应用程序中比 运行固定查询更常见。
绑定参数和query preparation是两个不同的东西。你可以做一个或另一个或两者都做。
您需要绑定参数以防止SQL注入。但是,有些东西不能作为参数传递(例如 ORDER BY 列表),在这种情况下,您可以将所需的 SQL 语法直接连接到 SQL 字符串中。这称为 "dynamic SQL",通常应仅使用列入白名单的字符串以防止 SQL 注入。
所以回答(我认为是)你的问题:动态 SQL 是允许的,因为有些情况没有被绑定参数覆盖。
既然所有SQL查询都应该准备好防止SQL注入,为什么我们允许编写和执行非准备查询?这看起来是不是违反直觉?
即使您需要使用准备语句,也无法阻止通过变量替换创建准备语句。例如
$sql = "SELECT * FROM someTable WHERE id = $id";
$stmt = $conn->prepare($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'));
您可能会发现这在您的应用程序中比 运行固定查询更常见。
绑定参数和query preparation是两个不同的东西。你可以做一个或另一个或两者都做。
您需要绑定参数以防止SQL注入。但是,有些东西不能作为参数传递(例如 ORDER BY 列表),在这种情况下,您可以将所需的 SQL 语法直接连接到 SQL 字符串中。这称为 "dynamic SQL",通常应仅使用列入白名单的字符串以防止 SQL 注入。
所以回答(我认为是)你的问题:动态 SQL 是允许的,因为有些情况没有被绑定参数覆盖。