0

是否可以利用既连接字符串又使用参数的准备好的语句?如果是这样,怎么做?

PreparedStatement prepstmt = 
    conn.prepareStatement("SELECT productId, price FROM products WHERE productId = ?" 
                     + "UNION SELECT productId, price FROM oldProducts WHERE productId = ?");

prepstmt.setString(1, productId);
prepstmt.setString(2, productId);

我的第一个想法是可以利用 usingproductId = 'a' OR 1=1\但我无法使其工作。

提前致谢!

4

1 回答 1

1

SQL 注入的风险并非来自连接固定字符串。我可以执行以下操作,这将是安全的:

String sql = "SELECT " + "*" + " FROM " + "mytable" + " WHERE " + ...

关键是这个字符串的每个部分在 Java 编译时都是固定的。它都不是来自任何不安全的内容。

SQL 注入的风险部分是不安全的内容可能会在准备好之前输入您的 SQL 字符串。因此,不安全的内容会影响准备期间解析的 SQL 语法。

一些开发人员认为“不安全内容”与用户输入相同,但它可能来自其他来源,例如读取文件、来自 Web 服务的响应,甚至是先前存储在数据库中的字符串数据。

未知内容使用参数,其余使用固定字符串,你会很安全。是否通过连接构建查询并不重要,只要连接的每个子字符串本身都是安全的。

PS:记得用空格填充你的子字符串。您在上面显示的示例将导致以下结果:

SELECT productId, price FROM products WHERE productId = ?UNION SELECT productId, price FROM oldProducts WHERE productId = ?

这可能是一个问题,具体取决于 SQL 解析器,因为您可能需要一个空格分隔?UNION- 确保它是? UNION

于 2020-12-03T21:37:10.520 回答