为什么参数化查询允许将用户数据移出字符串进行解释?

时间:2018-06-08 17:53:14

标签: sql sql-injection code-injection

来自https://en.wikipedia.org/wiki/Code_injection#Preventing_problems

  

为防止代码注入问题,请使用安全的输入和输出处理,例如:

     
      
  • 使用API​​,如果使用得当,对所有输入字符都是安全的。 参数化查询(也称为"编译查询","预处理语句","绑定变量")允许将用户数据移出字符串进行解释另外,Criteria API [7]和类似的API远离要创建和解释的命令字符串的概念。
  •   

我想知道如何以及为什么"参数化查询(也称为"编译查询","准备好的语句","绑定变量")允许用于将用户数据移出字符串以进行解释"并防止或减轻代码注入问题?

您还可以提供一些解释示例吗?

感谢。

1 个答案:

答案 0 :(得分:3)

编译查询使用数据库理解的特殊语法。它们通常为参数添加占位符,例如:

select * from applicant where name = ?

select * from applicant where name = :name

确切的语法取决于特定的技术:JDBC,ODBC等。

现在,一旦将这些查询发送到数据库(没有特定的参数值),数据库就会保存"他们。稍后(通常在同一个数据库会话中),您可以多次运行它们,每次只提供参数值。

SQL注入安全

它们也可以安全地防止SQL注入。例如,如果在上一个查询中使用值Mary而不是简单值(如x'; delete from applicant; --),则数据库将安全地工作。它会运行如下:

select * from applicant where name = 'x; delete from applicant; --'

此查询可能无法找到任何内容并且安全。

如果您没有使用编译查询,但只是决定将SQL连接为字符串,您可以执行以下操作:

String sql = "select * from applicant where name = '" + param1 + "'";

并最终得到UNSAFE查询:

select * from applicant where name = 'x'; delete from applicant; --

这个会运行两个查询。第二个将删除表中的所有信息。可能不是你想要的。