准备好的语句如何帮助我们防止SQL注入攻击?

维基百科说:

预处理语句对SQL注入具有弹性,因为 参数值,稍后使用不同的 协议,不需要正确转义。如果原始语句 模板不能从外部输入派生,SQL注入不能 发生。

我不太明白其中的原因。如何用简单的英语和一些例子来简单地解释?


当前回答

在SQL Server中,使用准备好的语句绝对是防注入的,因为输入参数不构成查询。这意味着执行的查询不是动态查询。 SQL注入易受攻击语句的示例。

string sqlquery = "select * from table where username='" + inputusername +"' and password='" + pass + "'";

现在,如果inoutusername变量的值是类似于a'或1=1——,这个查询现在变成:

select * from table where username='a' or 1=1 -- and password=asda

其余部分在——之后被注释,所以它永远不会被执行和绕过,就像使用下面的预处理语句示例一样。

Sqlcommand command = new sqlcommand("select * from table where username = @userinput and password=@pass");
command.Parameters.Add(new SqlParameter("@userinput", 100));
command.Parameters.Add(new SqlParameter("@pass", 100));
command.prepare();

所以实际上你不能发送另一个参数,从而避免SQL注入…

其他回答

基本上,通过准备好的语句,来自潜在黑客的数据被视为数据——它不可能与应用程序SQL混合和/或被解释为SQL(当传入的数据直接放入应用程序SQL时可能发生)。

这是因为预处理语句首先“准备”SQL查询,以找到一个有效的查询计划,然后发送可能来自表单的实际值——在查询实际执行的时候。

更多信息请点击这里:

准备好的语句和SQL注入

关键短语是不需要正确转义。这意味着你不需要担心人们试图插入破折号、撇号、引号等等……

一切都为你安排好了。

在SQL Server中,使用准备好的语句绝对是防注入的,因为输入参数不构成查询。这意味着执行的查询不是动态查询。 SQL注入易受攻击语句的示例。

string sqlquery = "select * from table where username='" + inputusername +"' and password='" + pass + "'";

现在,如果inoutusername变量的值是类似于a'或1=1——,这个查询现在变成:

select * from table where username='a' or 1=1 -- and password=asda

其余部分在——之后被注释,所以它永远不会被执行和绕过,就像使用下面的预处理语句示例一样。

Sqlcommand command = new sqlcommand("select * from table where username = @userinput and password=@pass");
command.Parameters.Add(new SqlParameter("@userinput", 100));
command.Parameters.Add(new SqlParameter("@pass", 100));
command.prepare();

所以实际上你不能发送另一个参数,从而避免SQL注入…

简单的例子:

  "select * from myTable where name = " + condition;

如果用户输入是:

  '123'; delete from myTable; commit;

查询将像这样执行:

  select * from myTable where name = '123'; delete from myTable; commit;
ResultSet rs = statement.executeQuery("select * from foo where value = " + httpRequest.getParameter("filter");

让我们假设在Servlet中有这个。如果一个恶意的人传递了一个坏的值为'过滤器',你可能会黑你的数据库。