我正在尝试用 Java 编写一个准备好的语句来有条件地过滤包含或不包含特定字段的行。然而,Sonar 给了我一个 linter 错误:
This use of java/sql/Connection.prepareStatement(Ljava/lang/String;)Ljava/sql/PreparedStatement; can be vulnerable to SQL injection (with JDBC)
。查询如下所示:
String query = "SELECT * from my_table t " +
"WHERE t.connection_id IS " + (connected ? "NOT " : "") + "NULL " +
(search.isEmpty() ? "" : "AND (t.source LIKE ?)");
PreparedStatement statement = connection.prepareStatement(query);
有趣的是,当我只进行搜索时,我没有收到错误 - 所以我预计搜索和过滤器都会出现错误,或者两者都不会出现错误。
我也尝试将第二行更改为:
"WHERE " + (connected ? "t.connection_id IS NOT NULL " : "t.connection_id IS NULL ") +
但没有变化。我错过了什么吗?我可以采取什么措施来修复该错误,还是应该忽略它?
您的查询(如图所示)是正确的,并且实际上不容易受到 SQL 注入的攻击。也就是说,编写静态代码分析器存在困难。它看到您正在构建一个 SQL 查询并根据输入进行连接,这是 SQL 注入漏洞的经典标记。
在这种情况下,重构代码可能比尝试修复工具更容易。像声纳这样的工具确实很棒,它们可以找到很多好东西,但有时你会得到误报。我不会只是忽略它......你不想养成忽略有关 SQL 注入之类的警告的习惯。