将没有参数的查询传递给 PreparedStatement 是否安全?

use*_*608 3 java sql-injection jdbc prepared-statement

我对 Java 很陌生,所以肯定这将是一个愚蠢的问题。

我经常读到,在处理被视为字符串的查询时,必须意识到 SQL 注入的风险。我还读到使用 PreparedStatements 是防止此类风险的好方法,但它们通常与查询中的位置参数一起使用(由问号表示?)。

如果我只有一个没有参数的“常量”查询(即,我没有要在查询中插入的变量),情况如何?我是否仍然需要将表单中的查询传递 "SELECT * from Table where col1 = ? and col2 = ?" 给 PreparedStatement 以防止 SQL 注入?

或者我可以通过 "SELECT * from Table where col1 = 123 and col2 = 'abc'" 吗?

我有这个代码:

public ResultSet mySelectMethod(String query, Connection conn) {
    ResultSet rset = null;
    try {
        PreparedStatement st = conn.PreparedStatement(query);   //I am unsure about this assignment
        rset = st.executeQuery();
    } catch (SQLException e) {
        System.out.println(e);
    }
    return rset;
}
...
...
// method call:
String myQuery = "SELECT colA FROM table_name WHERE table_id = 192837465";
ResultSet myResultSet = mySelectMethod(myQuery, myConn);
Run Code Online (Sandbox Code Playgroud)

这是安全的还是有任何问题?

Arv*_*ash 6

由于您没有向查询传递任何参数,因此您没有 SQL 注入的风险。此外,您不需要PreparedStatement为您的情况。你可以Statement改用。

String query = "SELECT * from Table where col1 = 123 and col2 = 'abc'";

try (Statement st = conn.createStatement()) {
    ResultSet rset = stmt.executeQuery(query);

    while (rs.next()) {
        //...
    }
} 
Run Code Online (Sandbox Code Playgroud)

除此之外,正如您在上面的代码中看到的,您应该尝试使用自动关闭资源的try-with-resorces 语句