提问人:Tim 提问时间:6/9/2018 最后编辑:CommunityTim 更新时间:6/9/2018 访问量:54
为什么参数化查询允许将用户数据移出要解释的字符串?
Why do Parameterized queries allow for moving user data out of string to be interpreted?
问:
从 https://en.wikipedia.org/wiki/Code_injection#Preventing_problems
为防止代码注入问题,请使用安全的输入和输出处理,例如:
- 使用如果使用得当,可以防止所有输入字符使用的 API。参数化查询(也称为“编译查询”、“预准备语句”、“绑定变量”)允许将用户数据移出要解释的字符串。此外,Criteria API[7] 和类似的 API 摆脱了要创建和解释的命令字符串的概念。
我想知道“参数化查询(也称为”编译查询“、”预准备语句“、”绑定变量“)如何以及为什么允许将用户数据移出字符串进行解释”并防止或缓解代码注入问题?
您能提供一些例子来解释吗?
谢谢。
答:
3赞
The Impaler
6/9/2018
#1
编译的查询使用数据库理解的特殊语法。他们通常会为以下参数添加占位符:
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; --
这个将运行两个查询。第二个将从表中删除所有信息。可能不是你想要的。
评论
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?如果是,你会如何一步一步地做?
评论