java代码中的SQL注入问题

时间:2018-05-07 15:31:22

标签: java prepared-statement sql-injection

我有以下主要方法,当扫描编码标准/规则时,显示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>

1 个答案:

答案 0 :(得分:2)

  

由于我的名字参数是动态的,我不能用prepareStatement设置它。

当然可以,您只需要同时动态处理SQL文本和参数。

您还应该使用try-with-resources来正确关闭ConnectionPreparedStatementResultSet个对象。

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子句相同