为什么准备好的报表可以防止注射?

时间:2012-06-26 22:28:12

标签: php mysql sql-injection

我的目的是为了获得对预准备语句的基本理解,并且我认为它们可以防止SQL注入攻击。但是我还没有明白他们为什么要防止这些攻击。我知道有类似的问题,但我没有找到完全令人满意的答案。

示例 - 非常不安全的代码
所以这里我们有最基本的方式与我们的数据库进行通信:

$query = "SELECT * FROM users where id=$username";

没有任何保护,用户可以输入恶意代码,从而“欺骗”数据库引擎执行毁灭性的查询:

$username = "1; DROP TABLE users;"
SELECT * FROM users where id=1; DROP TABLE users;

我不明白的是,准备好的声明如何设法“过滤掉”这些数据。它背后的机制是什么,它不会引诱数据库生成如上所示的SQL查询?就像逃避某些字符一样简单,比如上面例子中的分号,还是更复杂?

如果我要像示例中那样进行精确的注入攻击,但是通过预准备语句运行它,那么什么样的命令字符串会到达数据库引擎?

3 个答案:

答案 0 :(得分:1)

准备好的语句不只是添加文本,而是将其作为数据发送,并让数据库单独处理。因为实际上数据库实际上并不使用SQL语句,所以它使用它们的“编译”版本。

不太清楚我是否清楚,但它在于如何将查询发送到数据库。

答案 1 :(得分:0)

准备语句通常用于使用参数绑定。它实际上是参数绑定,可以隔绝这些类型的攻击。您可以在不使用预准备语句的情况下使用参数绑定。

准备语句提供的第二级保护是每个语句都是单个语句(因此使用;创建两个语句将不起作用)。

作为一般规则,为了免受注入攻击,必须根据非任何外部输入的数据准备预备语句。

答案 2 :(得分:0)

基本上,如果你使用标准的无类型参数绑定,你将得到

SELECT * FROM users where id='1; DROP TABLE users;'

哪个会在数据库上出错,但不会造成任何伤害。

请理解,这不是正在运行的东西

SELECT * FROM users where id='$username' 

带有适当的转义$username - 它发生在数据库访问堆栈的较低层。