4

http://php.net/manual/en/pdo.prepared-statements.php

如果应用程序专门使用预准备语句,开发人员可以确定不会发生 SQL 注入(但是,如果查询的其他部分是使用非转义输入构建的,则仍然可能发生 SQL 注入)。

某些输入未转义的可能场景是什么?如果所有其他输入都使用 PDO 进入数据库,这是否可能?

我正在考虑使用 mysql_* 函数处理其他输入而不使用 mysql_real_escape_string 转义的场景。还有什么可能构成威胁的吗?

非常感谢。问候

4

3 回答 3

8

这意味着您不能直接使用不受信任的值,例如作为列名或表名 - 或作为 LIMIT 参数。

例如,这是安全的:

$query = "SELECT * FROM tbl WHERE col = ?";

虽然这些不是:

$query = 'SELECT * FROM tbl WHERE col = ? LIMIT ' . $_GET['limit'];
$query = 'SELECT * FROM tbl WHERE ' . $_GET['field'] . ' = ?';
$query = "SELECT * FROM tbl WHERE col = ? AND othercol = '" . $_GET['other'] . "'";
$query = 'SELECT * FROM ' . $_GET['table'] . ' WHERE col = ?';

基本上,准备好的语句的占位符用于在经典查询中在单引号内使用转义值的地方。

如果您想知道为什么数据库通常不支持表名之类的占位符:除了动态表/列名并不常见的事实外,数据库引擎通常会在准备好准备好的语句时对其进行优化。但是,如果不确切知道访问了哪些表/列,则无法正确完成此操作。

于 2012-05-17T12:19:40.560 回答
2

考虑一下:

$sql = "SELECT * FROM ".$_GET['tablename']." WHERE somecol = ?";

因为我使用未转义的用户输入填充了表名,所以即使您已经转义了传递给比较的值,也可以传入例如public_table p LEFT JOIN hidden_table h ON h.id = p.id并获得您不希望我传递的结果。somecol

关键是,虽然准备好的语句可以安全地转义您在查询中传递给 a 的任何用户输入?,但它们无法转义在您将字符串传递给之前已经存在于字符串中的数据prepare()

于 2012-05-17T12:22:44.117 回答
0

这意味着不要被诱使认为 PDO 是灵丹妙药……如果您使用准备好的语句,您仍然会很脆弱。

于 2012-05-17T12:21:45.800 回答