我正在考虑像这样的例子:
请求使用参数在网址(通过任何方式)命中页面。 example.com/api/page?name=bob
。我的理解是你应该做一个准备好的声明来获取$_POST[name]
参数,并确保它不是什么时髦,但它是通过评估表达式来实现的。
我的第一个问题是:它是如何做到的(评估表达式)?
我的第二个问题是:
如果用户输入" SELECT * FROM users"或" DROP TABLE用户"传递给$_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()
如何运作?我所描述的实际上可以提出一个安全漏洞吗?我需要一些帮助来理解这一点。
答案 0 :(得分:4)
为了清除任何困惑,我正在做的是:
$pdo = new PDO('..'); $sql = 'SELECT id FROM users WHERE username = :username'; $statement = $pdo->prepare($sql); $statement->bindParam(':username', $_POST['username']);
问题是,如果$ _POST ['用户名']包含' SELECT * FROM users' (或任何其他查询)?
此查询将使用用户名" SELECT * FROM users"返回所有用户的ID。
通过传递$ _POST ['用户名']作为参数,数据库知道任何字符串$ _POST ['用户名']可能包含它不是查询的一部分。它只是一个字符串。
这可以防止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'
没有工作。因为您不能在参数中包含查询。嗯,你可以,但他们不会被处决。