首页 > 解决方案 > java代码中的SQL注入问题

问题描述

当扫描编码标准/规则时,我有以下主要方法显示 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. 什么是最佳解决方案?

注意:在块中使用 2 个不同的查询if-else不会解决目的,因为我有 7 个不同的参数要动态设置,这将引入开销,因为会有很多查询。

标签: javaprepared-statementsql-injection

解决方案


由于我的名称参数是动态的,我无法使用preparedStatement 进行设置。

当然可以,您只需要同时动态处理 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,则与 noWHERE子句相同。name


推荐阅读