SELECT 在 SELECT PDO 预处理语句中
SELECT within SELECT PDO prepared statement
我在想这样的例子:
请求到达 url 的页面(以任何方式),带有参数。 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')
第二个 select 作为用户输入参数 - 所以 $_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()
是如何工作的?我所描述的实际上是否存在安全漏洞?我需要一些帮助来理解这一点。
To clear any confusion, what i'm doing is this:
$pdo = new PDO('..');
$sql = 'SELECT id FROM users WHERE username = :username';
$statement = $pdo->prepare($sql);
$statement->bindParam(':username', $_POST['username']);
Question is, what if $_POST['username'] contains 'SELECT * FROM users' (or any other query) ?
此查询将 return 用户名为 "SELECT * FROM users" 的所有用户的 ID。
通过将 $_POST['username'] 作为参数传递,数据库知道 $_POST['username'] 可能包含的任何字符串都不是查询的一部分。它只是一个字符串。
这可以防止 SQL 注入,因为参数不会被执行。这也意味着
SELECT name, continent FROM world
WHERE continent IN
(SELECT continent FROM world WHERE name='Brazil')
the second select acting as the user input parameter - so $_POST['name'] contains this query SELECT continent FROM world WHERE name='Brazil'
行不通。因为您不能在参数中包含查询。好吧,你可以,但他们不会被处决。
我在想这样的例子:
请求到达 url 的页面(以任何方式),带有参数。 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')
第二个 select 作为用户输入参数 - 所以 $_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()
是如何工作的?我所描述的实际上是否存在安全漏洞?我需要一些帮助来理解这一点。
To clear any confusion, what i'm doing is this:
$pdo = new PDO('..'); $sql = 'SELECT id FROM users WHERE username = :username'; $statement = $pdo->prepare($sql); $statement->bindParam(':username', $_POST['username']);
Question is, what if $_POST['username'] contains 'SELECT * FROM users' (or any other query) ?
此查询将 return 用户名为 "SELECT * FROM users" 的所有用户的 ID。
通过将 $_POST['username'] 作为参数传递,数据库知道 $_POST['username'] 可能包含的任何字符串都不是查询的一部分。它只是一个字符串。
这可以防止 SQL 注入,因为参数不会被执行。这也意味着
SELECT name, continent FROM world WHERE continent IN (SELECT continent FROM world WHERE name='Brazil')
the second select acting as the user input parameter - so $_POST['name'] contains this query SELECT continent FROM world WHERE name='Brazil'
行不通。因为您不能在参数中包含查询。好吧,你可以,但他们不会被处决。