准备好的语句如何帮助我们防止SQL注入攻击?
维基百科说:
预处理语句对SQL注入具有弹性,因为 参数值,稍后使用不同的 协议,不需要正确转义。如果原始语句 模板不能从外部输入派生,SQL注入不能 发生。
我不太明白其中的原因。如何用简单的英语和一些例子来简单地解释?
准备好的语句如何帮助我们防止SQL注入攻击?
维基百科说:
预处理语句对SQL注入具有弹性,因为 参数值,稍后使用不同的 协议,不需要正确转义。如果原始语句 模板不能从外部输入派生,SQL注入不能 发生。
我不太明白其中的原因。如何用简单的英语和一些例子来简单地解释?
当前回答
基本上,通过准备好的语句,来自潜在黑客的数据被视为数据——它不可能与应用程序SQL混合和/或被解释为SQL(当传入的数据直接放入应用程序SQL时可能发生)。
这是因为预处理语句首先“准备”SQL查询,以找到一个有效的查询计划,然后发送可能来自表单的实际值——在查询实际执行的时候。
更多信息请点击这里:
准备好的语句和SQL注入
其他回答
简单的例子:
"select * from myTable where name = " + condition;
如果用户输入是:
'123'; delete from myTable; commit;
查询将像这样执行:
select * from myTable where name = '123'; delete from myTable; commit;
当您创建准备好的语句并将其发送到DBMS时,它将存储为SQL查询以供执行。
稍后将数据绑定到查询,以便DBMS使用该数据作为执行(参数化)的查询参数。DBMS不会使用你绑定的数据作为已经编译的SQL查询的补充;只是数据而已。
这意味着使用准备好的语句执行SQL注入从根本上是不可能的。预处理语句的本质及其与DBMS的关系阻止了这一点。
其思想非常简单——查询和数据分别发送到数据库服务器。 这是所有。
SQL注入问题的根源在于代码和数据的混合。
事实上,我们的SQL查询是一个合法的程序。 我们正在动态地创建这样一个程序,动态地添加一些数据。因此,数据可能会干扰程序代码,甚至改变它,正如每个SQL注入示例所显示的那样(所有PHP/Mysql中的示例):
$expected_data = 1;
$query = "SELECT * FROM users where id=$expected_data";
会产生一个常规查询吗
SELECT * FROM users where id=1
而这段代码
$spoiled_data = "1; DROP TABLE users;"
$query = "SELECT * FROM users where id=$spoiled_data";
会产生恶意序列吗
SELECT * FROM users where id=1; DROP TABLE users;
它可以工作,因为我们直接将数据添加到程序主体中,它成为程序的一部分,因此数据可能会改变程序,并且根据传递的数据,我们将有一个常规输出或用户删除的表。
而对于准备好的语句,我们不改变我们的程序,它保持不变 这就是重点。
我们首先向服务器发送一个程序
$db->prepare("SELECT * FROM users where id=?");
其中数据被一些称为参数或占位符的变量所取代。
注意,完全相同的查询被发送到服务器,其中没有任何数据!然后我们将数据与第二个请求一起发送,本质上与查询本身分离:
$db->execute($data);
所以它不会改变我们的程序,造成任何伤害。 很简单,不是吗?
我唯一需要补充的是,每个手册中都省略了:
预准备语句只能保护数据文字,但不能与任何其他查询部分一起使用。 因此,一旦我们必须添加一个动态标识符——例如,一个字段名——预处理语句就无法帮助我们。这件事我最近已经解释过了,我就不再重复了。
关键短语是不需要正确转义。这意味着你不需要担心人们试图插入破折号、撇号、引号等等……
一切都为你安排好了。
基本上,通过准备好的语句,来自潜在黑客的数据被视为数据——它不可能与应用程序SQL混合和/或被解释为SQL(当传入的数据直接放入应用程序SQL时可能发生)。
这是因为预处理语句首先“准备”SQL查询,以找到一个有效的查询计划,然后发送可能来自表单的实际值——在查询实际执行的时候。
更多信息请点击这里:
准备好的语句和SQL注入