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

Is it safe to pass a query with no parameters to PreparedStatement?

提问人:user14520608 提问时间:1/29/2021 最后编辑:Mark Rotteveeluser14520608 更新时间:1/29/2021 访问量:1777

问:

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

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

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

或者我可以通过吗?"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);

这安全还是有任何问题?

java jdbc 准备语句 sql 注入

评论

5赞 khelwood 1/29/2021
危险在于将外部输入直接插入到 SQL 查询中。执行已包含安全值的查询不会出现安全问题。
2赞 takendarkk 1/29/2021
"在处理被视为 String 的查询时 SQL 注入的风险“ 风险在于,当您从网页上的文本框中获取一些外部输入并将其直接放入您没有执行的 String 中时。这很好。
0赞 user14520608 1/29/2021
好的,所以基本上如果没有人将我的方法与外部输入一起使用(我只调用它来执行固定查询),就没有问题了。右?谢谢大家!
1赞 JayC667 1/29/2021
这里的答案很好地涵盖了这个问题。我真的非常建议你花时间去看看SQL注入(和许多其他注入)是如何工作的。因为它是一个非常常见的问题,所以它可能是最简单和最常见的攻击媒介。这通常很容易预防,但最重要的是:在设计软件时要始终牢记这一点。

答:

8赞 Arvind Kumar Avinash 1/29/2021 #1

由于您没有将任何参数传递给查询,因此不存在 SQL 注入的风险。此外,您的情况不需要。您可以改用。PreparedStatementStatement

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

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

    while (rs.next()) {
        //...
    }
} 

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

评论

0赞 user14520608 1/29/2021
谢谢!!我也可以使用Statement进行插入/更新/删除吗?还是只能通过 PreparedStatement 实现?
1赞 Arvind Kumar Avinash 1/29/2021
非常欢迎您!您可以将 Statement#executeUpdate 用于 、 或 语句。INSERTUPDATEDELETE