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

Why do Parameterized queries allow for moving user data out of string to be interpreted?

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

To prevent code injection problems, utilize secure input and output handling, such as:

  • Using APIs that, if used properly, are secure against all input characters. Parameterized queries (also known as "Compiled queries", "prepared statements", "bound variables") allows for moving user data out of string to be interpreted. Additionally Criteria API[7] and similar APIs move away from the concept of command strings to be created and interpreted.

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

能不能也举例说明一下?

谢谢。

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

select * from applicant where name = ?

select * from applicant where name = :name

具体语法取决于具体技术:JDBC、ODBC 等

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

SQL 注射安全

它们对 SQL 注入也是安全的。例如,如果在之前的查询中您使用值 x'; delete from applicant; -- 而不是 Mary 等简单值,则数据库将安全运行。它会 运行 类似于:

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; --

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