在SELECT PDO准备语句中选择SELECT

Rad*_*rei 6 php mysql security pdo prepared-statement

我在想一个这样的例子:

请求使用参数在网址(通过任何方式)访问页面.example.com/api/page?name=bob.我的理解是你应该做一个准备好的声明来获取$_POST[name]参数,并确保它不是什么时髦,但它通过评估表达式来实现.

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

我的第二个问题是:如果用户输入的内容沿着"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')
Run Code Online (Sandbox Code Playgroud)

第二个选择充当用户输入参数 - 因此$_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']);
Run Code Online (Sandbox Code Playgroud)

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

小智 5

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

$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'] 包含这个查询 SELECT continent FROM world WHERE name='Brazil'

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