SQL 即使在准备好的语句上也可以注入
Is SQL injection possible even on a prepared statement
我在 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 注入查询的(单引号)'被转义(/')none 似乎有效。
如果上面的代码中有任何 SQL 注入 queries/techniques 可用于执行 SQL 注入,请建议我。
这个查询:String query = "SELECT * FROM Users WHERE username=? and password=?";
是安全的,因为无论参数是什么,它仍然会作为一个简单的 select 执行。顶多浏览完一整个table.
但是准备好的语句只是一个工具,(糟糕的)程序员可能仍然会滥用它。
我们来看下面的查询
String query = "SELECT id, " + paramName + " FROM Users WHERE username=? and password=?";
其中 paramName
是参数名称。它仅与 paramName
一样安全,因为您直接使用变量来构建将由数据库引擎解析的字符串。这里 PreparedStatement
无能为力,因为 JDBC 不允许参数化列名。
所以这里的规则是:
- 如果可以,请避免这种构造!
- 如果您真的需要它,请仔细检查(正则表达式、允许的字符串列表等)
paramName
不能是您期望的任何内容,因为 控制是唯一的预防措施 反对 SQL 注入
我在 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 注入查询的(单引号)'被转义(/')none 似乎有效。
如果上面的代码中有任何 SQL 注入 queries/techniques 可用于执行 SQL 注入,请建议我。
这个查询:String query = "SELECT * FROM Users WHERE username=? and password=?";
是安全的,因为无论参数是什么,它仍然会作为一个简单的 select 执行。顶多浏览完一整个table.
但是准备好的语句只是一个工具,(糟糕的)程序员可能仍然会滥用它。
我们来看下面的查询
String query = "SELECT id, " + paramName + " FROM Users WHERE username=? and password=?";
其中 paramName
是参数名称。它仅与 paramName
一样安全,因为您直接使用变量来构建将由数据库引擎解析的字符串。这里 PreparedStatement
无能为力,因为 JDBC 不允许参数化列名。
所以这里的规则是:
- 如果可以,请避免这种构造!
- 如果您真的需要它,请仔细检查(正则表达式、允许的字符串列表等)
paramName
不能是您期望的任何内容,因为 控制是唯一的预防措施 反对 SQL 注入