2

我在 Stack Overflow 上阅读了很多关于如何通过使用准备好的语句来防止 SQL 注入的文章

但是有没有办法在准备好的语句上进行 SQL 注入,或者它是 100% 安全的吗?

下面是我的java代码

 String query = "SELECT * FROM Users WHERE username=? and password=?";

 ps=con.prepareStatement(query);  

 ps.setString(1,username);
 ps.setString(2,password);

 rs = ps.executeQuery();

 status = rs.next();

 if(status==true){
.....
}else{
....
}

我尝试了一些sql注入查询,例如

一些输入:

SELECT * FROM users WHERE username = 'xxx@xxx.xxx' OR 1 = 1 LIMIT 1 -- ' ] AND password = md5('1234');

SELECT * FROM users WHERE email = 'xxx@xxx.xxx' AND password = md5('xxx') OR 1 = 1 -- ]');

我还尝试了更多查询,但由于(单引号)'被转义(/'),所有 SQL 注入查询似乎都不起作用。

如果有任何 SQL 注入查询/技术可用于在上述代码中进行 SQL 注入,请建议我。

4

1 回答 1

4

这个查询 :String query = "SELECT * FROM Users WHERE username=? and password=?";是安全的,因为无论参数是什么,它仍然会作为一个简单的选择执行。最多,它会结束浏览整个表。

但是准备好的语句只是一个工具,(坏的)程序员仍然可能滥用它。

让我们看看下面的查询

String query = "SELECT id, " + paramName + " FROM Users WHERE username=? and password=?";

whereparamName将是参数名称。它只是安全paramName的,因为您直接使用变量来构建将由数据库引擎解析的字符串。这里PreparedStatement无济于事,因为 JDBC 不允许参数化列名。

所以这里的规则是:

  • 如果可以的话,避免这样的结构!
  • 如果你真的需要它,请仔细检查(正则表达式、允许的字符串列表等),paramName它不能是你所期望的以外的任何东西,因为该控制是防止SQL 注入的唯一预防措施
于 2015-05-11T13:50:20.917 回答