SELECT PDO 准备好的语句中的 SELECT [重复]

Posted

技术标签:

【中文标题】SELECT PDO 准备好的语句中的 SELECT [重复]【英文标题】:SELECT within SELECT PDO prepared statement [duplicate] 【发布时间】:2015-08-25 08:28:15 【问题描述】:

我在想这样一个例子:

请求在带有参数的 url(以任何方式)处访问页面。 example.com/api/page?name=bob。我的理解是你应该做一个准备好的语句来获取$_POST[name]parameter 并确保它不是什么时髦的东西,但它是通过评估表达式来实现的。

我的第一个问题是:它是如何做到的(评估表达式)?

我的第二个问题是: 如果用户输入了类似于“SELECT * FROM users”或“DROP TABLE users”的内容并传递给$_POST['name'] 参数(最后是?name=bob),在这种情况下会发生什么?

作为一个例子,最终的查询将类似于

SELECT name, continent FROM world
WHERE continent IN
(SELECT continent FROM world WHERE name='Brazil')

第二个选择充当用户输入参数 - 所以$_POST['name'] 包含此查询SELECT continent FROM world WHERE name='Brazil'

最后,我的第三个问题是我如何才能防止类似的事情发生?

我猜 PDO 是专门为防止查询中的查询而设计的(?),但是在阅读了一下之后我仍然很困惑。

我仍在学习所有这些,所以如果我的询问不够清楚或不够具体,请告诉我,我会尽力解决。

编辑: 为了消除任何混乱,我正在做的是:

$pdo = new PDO('..');
$sql = 'SELECT id FROM users WHERE username = :username';
$statement = $pdo->prepare($sql);
$statement->bindParam(':username', $_POST['username']);

问题是,如果$_POST['username'] 包含'SELECT * FROM users'(或任何其他查询)怎么办? prepare() 是如何工作的?我所描述的实际上是否存在安全漏洞?我需要一些帮助来理解这一点。

【问题讨论】:

不要使用外部输入作为查询的一部分。为了防止 SQL 注入漏洞,请使用参数化查询。 @WernerHenze 请查看更新后的问题。查询是“参数化的”。 ***.com/questions/134099/… 参数化代码不会被执行,因此恶意查询将被视为一个字符串。 @CosLu 谢谢先生/女士!我现在将关闭这个问题,因为它似乎是多余的,在其他地方得到了回答。再次感谢您。 【参考方案1】:

为了消除任何混乱,我正在做的是:

$pdo = new PDO('..'); $sql = 'SELECT id FROM users WHERE username = :username'; $statement = $pdo->prepare($sql); $statement->bindParam(':username', $_POST['username']);

问题是,如果 $_POST['username'] 包含“SELECT * FROM users”(或任何其他查询)怎么办?

此查询将返回用户名为“SELECT * FROM users”的所有用户的 ID。

通过传递 $_POST['username'] 作为参数,数据库知道任何字符串 $_POST['username'] 可能包含它不是查询的一部分。这只是一个字符串。

这可以防止 SQL 注入,因为该参数不会被执行。这也意味着

SELECT name, continent FROM world WHERE continent IN (SELECT continent FROM world WHERE name='Brazil')

作为用户输入参数的第二个选择 - 所以 $_POST['name'] 包含这个查询 SELECTcontinent FROM world WHERE name='Brazil'

行不通。因为您不能在参数中包含查询。好吧,你可以,但他们不会被处决。

【讨论】:

从 cmets 到我的问题。仍会将您的答案标记为已接受。泰。

以上是关于SELECT PDO 准备好的语句中的 SELECT [重复]的主要内容,如果未能解决你的问题,请参考以下文章

带有准备好的语句的 PDO bindParam() 不起作用

了解 PDO 准备好的语句和绑定参数

PDO准备好的语句是否足以阻止SQL注入?

PDO - 使用准备好的语句将所有 sql 数据放入 html 表中

从 mysql_query 转换为准备好的语句 (mysqli/PDO)?必要的?

如何将 pdo 的准备好的语句用于 order by 和 limit 子句?