我有以下主要方法,当扫描编码标准/规则时,显示SQL注入漏洞(因为字符串连接在这里完成)。
public static void main(String[] args) {
boolean flag = false;
String name = "";
String subName = "abhi";
try {
Class.forName("org.postgresql.Driver");
Connection c = DriverManager.getConnection("url","user", "password");
if(flag==true){
name = "LIKE '%'";
} else {
name = "= LOWER('" + subName + "')";
}
Statement s = c.createStatement();
String query = "SELECT * FROM xyz WHERE name "+name;
ResultSet rs = s.executeQuery(query);
while(rs.next()){
System.out.println(":"+rs.getString(1));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException se) {
se.printStackTrace();
}
}
我想删除SQL注入漏洞。由于我的name
参数是动态的,因此我无法使用preparedStatement
进行设置。什么是最佳解决方案?
注意:在if-else
块中使用2个不同的查询无法解决问题,因为我有7个不同的参数需要动态设置,这会引入开销,因为会有很多查询。< / p>
答案 0 :(得分:2)
由于我的名字参数是动态的,我不能用prepareStatement设置它。
当然可以,您只需要同时动态处理SQL文本和参数。
您还应该使用try-with-resources来正确关闭Connection
,PreparedStatement
和ResultSet
个对象。
boolean flag = false;
String subName = "abhi";
try (Connection c = DriverManager.getConnection("url","user", "password")) {
String sql = "SELECT *" +
" FROM xyz" +
" WHERE name " + (flag ? "LIKE '%'"
: "= LOWER(?)");
try (PreparedStatement s = c.prepareStatement(sql)) {
if (! flag)
s.setString(1, subName);
try (ResultSet rs = s.executeQuery()) {
while (rs.next()) {
System.out.println(":"+rs.getString(1));
}
}
}
} catch (SQLException se) {
se.printStackTrace();
}
仅供参考: WHERE name LIKE '%'
与WHERE name IS NOT NULL
相同,如果WHERE
列不可为空,则与无name
子句相同