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

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

提问人:Tim 提问时间:6/9/2018 最后编辑:CommunityTim 更新时间:6/9/2018 访问量:54

问:

从 https://en.wikipedia.org/wiki/Code_injection#Preventing_problems

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

  • 使用如果使用得当,可以防止所有输入字符使用的 API。参数化查询(也称为“编译查询”、“预准备语句”、“绑定变量”)允许将用户数据移出要解释的字符串。此外,Criteria API[7] 和类似的 API 摆脱了要创建和解释的命令字符串的概念。

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

您能提供一些例子来解释吗?

谢谢。

sql 代码注入

评论

1赞 dfundako 6/9/2018
我猜有数以千计的网站,其中包含 sql 注入的深入解释和示例、sql 注入的定义以及每个数据库平台的缓解技术。您要求某人就一个有大量文档记录且只需谷歌搜索即可的主题提供解释。

答:

3赞 The Impaler 6/9/2018 #1

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

select * from applicant where name = ?

select * from applicant where name = :name

确切的语法取决于具体的技术:JDBC、ODBC 等。

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

SQL注入安全

它们对 SQL 注入也是安全的。例如,如果在上一个查询中,而不是使用简单值(如您使用的值),则数据库将安全地工作。它会运行如下:Maryx'; 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; --

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

评论

0赞 Tim 6/9/2018
谢谢。(1)“一旦这些查询被发送到数据库(没有特定的参数值),数据库就会保存它们。DBMS 是否将编译的查询以存储过程的形式保存在 DBMS 服务器上?(2)“如果你没有使用编译的查询,而只是决定将SQL连接成一个字符串”,那么如何一步一步地完成呢?是否需要在 DBMS 服务器上创建存储过程,并且该存储过程接受来自用户的参数并将该参数追加到查询的末尾?
0赞 The Impaler 6/9/2018
你并没有真正看到数据库的底层。例如,在 JDBC 中,您可以使用类似 .然后,使用 或其他参数运行(多次)次。st = connection.prepareStatement("select * from applicant where name = ?")st.setString('Mary'); st.executeQuery();
0赞 Tim 6/9/2018
谢谢。关于(2),是否可以直接在SQL客户端/服务器中完成,而不使用其他编程语言和驱动程序,例如JDBC?如果是,你会如何一步一步地做?