首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过preparedStatement的SQL注入漏洞

通过preparedStatement的SQL注入漏洞
EN

Stack Overflow用户
提问于 2014-07-29 20:59:11
回答 4查看 2.8K关注 0票数 1

像这样的陈述

代码语言:javascript
复制
String query = "SELECT * FROM users WHERE userid ='"+ userid + "'" + " AND password='" + password + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);

符合SQL注入的条件。但是,PreparedStatement如何帮助防止SQL注入?考虑以下情况:

代码语言:javascript
复制
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE userid=? AND password=?");
stmt.setString(1, userid);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();

如果有人进入userId = "abc"password = "1=1",因为这也将被视为有效字符串.

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-07-29 21:04:31

保护您的确切方式取决于数据库,但是有两个明显的选项:

  • 数据库驱动程序可以执行字符串内插并生成SQL语句,以确保正确转义所有参数。
  • 数据库驱动程序可以按照您指定的那样将SQL传递给数据库,并通过一个完全独立的通道传递参数的值,该通道不需要任何转义,因为它只包含值。

在我看来,后者是一个更明智的解决方案,因为它允许数据库缓存查询计划,承认两个查询与参数值完全相同。我希望任何现代数据库都能在其本机通信协议中支持这一点。

票数 6
EN

Stack Overflow用户

发布于 2014-07-29 22:22:09

代码语言:javascript
复制
    String query = "SELECT * FROM users WHERE userid ='"+ userid + "'" + " AND password='" + password + "'";

在这里,如果您试图演示sql注入,密码的值可能类似于:‘OR 1=1 OR ''='

然后将发送到DB服务器执行的结果SQL为-

代码语言:javascript
复制
SELECT * FROM users WHERE userid ='abc' AND password='' OR 1=1 OR ''=''

因此,它从表中选择所有条目,而不管用户名和密码如何,因为userid ='abc‘和=’OR,1=1‘=’‘都是真的。任何未经授权的人都可以访问所有用户的数据。

如第二条语句使用参数化准备语句-

它将使用userid = "abc“和密码=”‘OR 1=1 OR’=‘’搜索表中的条目。

由于准备好的语句是在DB服务器中预编译的,也就是说,首先,空白查询从用户选择* userid=在哪里?然后将password=?发送到服务器,服务器将对其进行编译,然后将数据(参数)单独发送到db (执行时)。数据,即密码= ‘OR 1=1 OR’‘=’‘由JDBC驱动程序作为字符串文本发送。然后DB服务器强制将其用作有效参数,而不是sql查询。

票数 3
EN

Stack Overflow用户

发布于 2014-07-29 21:02:23

关于第二个例子,

PreparedStatement stmt =connection.prepareStatement(“从用户中选择*”+“userid=?和password=?");stmt.setString(1,用户rs );stmt.setString(2,密码);ResultSet rs= stmt.executeQuery(); 如果有人输入userId = "abc“和密码= "1=1",因为这也将被视为有效字符串.

答案是肯定的,但是一个正确转义的字符串文字。因此,密码必须是1=1才能工作。要明确的是,它不受SQL注入的限制,因为这些变量是正确绑定的。

根据PreparedStatement.setString(int, String) Javadoc粗体加,

将指定的参数设置为给定的Java字符串值。驱动程序将其转换为LONGVARCHAR或LONGVARCHAR(取决于参数相对于驱动程序对VARCHAR值的限制的大小)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25024894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档