False Positive: CloseSql.ql reports a ResultSet that is already scoped by try-with-resources on its parent Statement.
- 主要語言
- CodeQL
- 星號
- 10.1k
- 分支
- 2.1k
- 平均合併
- 2 天 15 小時
- 30 天內合併 PR
- 141
描述
Version
codeql 2.24.3
## Checker
- Checker id: `Likely Bugs/Resource Leaks/CloseSql.ql`
- Checker description: This checker detects SQL resource objects (Connection, Statement, ResultSet) that are initialized locally and not guaranteed to be closed on method exit.
## Description of the false positive
This case should stay out of the result set. The `ResultSet` is created from a `Statement` that is itself managed by try-with-resources, together with the owning `Connection`. Once the `try` block exits, both parent resources are closed, and the `ResultSet` lifetime is covered by that ownership chain.
The alias on the `Statement` does not change that. It is still the same tracked resource.
## Affected test cases
### `NegCase7_Var3.java`
`stmtAlias` is just another reference to `originalStmt`. The query appears to lose that alias relationship and treats `rs` as if it were detached from the try-with-resources scope.
```java
// A locally initialized SQL ResultSet obtained via a method call on a Statement variable, where Statement is a transitive parent closeable resource, should not be flagged as unclosed.
package scensct.var.neg;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
public class NegCase7_Var3 {
public void test() throws Exception {
try (Connection conn = DriverManager.getConnection("jdbc:test");
Statement originalStmt = conn.createStatement()) {
// Alias the Statement
Statement stmtAlias = originalStmt;
// Always-true condition
if (conn != null) {
// Locally initialized ResultSet via method call on aliased Statement
ResultSet rs = stmtAlias.executeQuery("SELECT 1"); // [REPORTED LINE]
}
}
}
}
```
## Cause analysis
`Likely Bugs/Resource Leaks/CloseSql.ql` is supposed to report SQL resources that are not guaranteed to be closed. That is not what this sample is doing.
The only reason this gets reported is that the `Statement` is referenced through `stmtAlias` instead of its original local name. If the query stops recognizing parent-resource ownership after a trivial alias, it will produce noise in ordinary JDBC code where objects are routinely passed through locals before use.
This is an ownership-tracking false positive, not a real leak.
貢獻指南
研究方向
首先閱讀 Likely Bugs/Resource Leaks/CloseSql.ql 和 NegCase7_Var3.java 範例。針對使用別名的 Statement 重現該報告,並檢查父資源的所有權是如何追蹤的。當此案例中的 ResultSet 不再被回報,同時真正未關閉的 SQL 資源仍然受到涵蓋時,即表示完成。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- java
- 領域
- security
- Issue 類型
- 缺陷
- 難度
- 3/5
- 預估耗時
- 1-2 天
- 活躍度
- 冷清
- 描述清晰度
- 基本清楚
- 新手友好度
- 68/100