CodeQL 1.19 Java 分析更新解读:新安全查询、SQL 注入检测扩展与 QL 库重构
发布时间:2026/9/26 2:44:06来源:尧图网络
静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security项目地址https://gitcode.com/gh_mirrors/co/codeql点击查看免费下载本指南基于 CodeQL 仓库 change-notes/1.19/analysis-java.md发布说明展开围绕 CodeQL 1.19 版本对 Java 分析能力的改进进行系统解读。文章覆盖新增的 Zip Slip 与 NumberFormatException 查询、现有安全查询的检测范围扩展、误报修复以及ControlFlowNode、FlowSources、ModulusAnalysis等 QL 库的变更。读完本文你将理解这些改动背后的检测原理、底层实现与查询文件的对应关系并能在实际项目中正确使用和配置这些查询。一、总体概览1.19 版本 Java 分析改进的核心脉络CodeQL 1.19 对 Java 分析即 java/ql 目录下的查询与库的改进可归纳为四条主线可追溯性提升为相关安全查询补充路径说明path explanations使数据流结果从只看结论升级为可逐跳追踪污染路径。新查询落地新增 2 个查询覆盖 Zip Slip任意文件写入与未捕获的NumberFormatException可靠性问题。既有查询增强与收敛SQL 注入类查询借助 Spring JDBC、MyBatis、Hibernate 框架 sink 模型获得更多检出同时多个查询修复误报。QL 库重构废弃ControlFlowNode与Expr/Stmt的直接相等性比较、扩展默认污点源集合、以ModulusAnalysis取代ParityAnalysis强化范围分析。下文依次展开并结合仓库源码给出可验证的依据。二、一般改进为安全查询补充路径说明Path explanations have been added to the relevant security queries. Use QL for Eclipse to run queries and explore the data flow in results.改动内容1.19 起与数据流相关的安全查询在输出结果时会附带路径说明即从污点源source到汇聚点sink的完整数据流路径而不只是最终告警位置。查看方式文档推荐使用 QL for Eclipse 插件运行查询并交互式探索结果中的数据流。今天该能力已内置于 VS Code 的 CodeQL 扩展中结果面板可直接展开路径视图逐跳查看。源码佐证此类查询在实现上以path-problem形式编写并引入PathGraph输出路径图。以新增的 Zip Slip 查询 java/ql/src/Security/CWE/CWE-022/ZipSlip.ql 为例其查询体正是import java import semmle.code.java.security.ZipSlipQuery import ZipSlipFlow::PathGraph from ZipSlipFlow::PathNode source, ZipSlipFlow::PathNode sink where ZipSlipFlow::flowPath(source, sink) select source.getNode(), source, sink, Unsanitized archive entry, which may contain .., is used in a $., sink.getNode(), file system operationkind path-problem与ZipSlipFlow::PathGraph的组合使得每条告警都能在结果中呈现完整传播链路——这正是 1.19 所强调的路径说明在实现层面的体现。三、新增查询一Zip Slip 任意文件写入漏洞java/zipslip发布说明给出的查询元信息如下查询标签用途Arbitrary file write during archive extraction (Zip Slip)java/zipslipsecurity, external/cwe/cwe-022识别允许任意文件覆盖的压缩包解压例程结果默认在 LGTM 上展示3.1 漏洞原理从 zip 等归档包中提取文件时归档条目ZipEntry携带的文件路径不受任何约束可能包含..这类目录穿越元素。若直接拼接该路径构造输出文件路径文件操作就会落到预期目录之外可能导致敏感信息泄露/删除或被攻击者通过改写意外文件影响系统行为。qhelp 文档 java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp 给出的示例若 zip 内含条目..\sneaky-file解压到c:\output时朴素拼接得到c:\output\..\sneaky-file实际会写入c:\sneaky-file。3.2 不安全写法反例仓库示例 java/ql/src/Security/CWE/CWE-022/examples/ZipSlipBad.javavoid writeZipEntry(ZipEntry entry, File destinationDir) { File file new File(destinationDir, entry.getName()); FileOutputStream fos new FileOutputStream(file); // BAD // ... write entry to fos ... }entry.getName()直接参与File构造未做任何规范化或前缀校验。3.3 修复建议正例仓库示例 java/ql/src/Security/CWE/CWE-022/examples/ZipSlipGood.javavoid writeZipEntry(ZipEntry entry, File destinationDir) { File file new File(destinationDir, entry.getName()); if (!file.toPath().normalize().startsWith(destinationDir.toPath())) throw new Exception(Bad zip entry); FileOutputStream fos new FileOutputStream(file); // OK // ... write entry to fos ... }qhelp 给出的修复要点路径规范化使用java.io.File.getCanonicalFile()或java.nio.file.Path.normalize()处理输出路径前缀校验String.startsWith(..)可行但更推荐java.nio.file.Path.startsWith(..)因为后者基于完整路径段比较可避免dest被dest-evil这类前缀误判备选方案对归档条目做白名单校验仅允许预期文件名。3.4 查询实现要点查询文件 ZipSlip.ql 的元数据说明其定位problem.severity error严重级别为错误、security-severity 7.5、precision high。检测逻辑委托给semmle.code.java.security.ZipSlipQuery库中的ZipSlipFlow污点追踪凡是未净化的归档条目名流入文件系统操作即被报告。由于security标签与 CWE-022 关联它默认进入安全查询套件因此在 LGTM 上默认展示结果。四、新增查询二未捕获的 NumberFormatExceptionjava/uncaught-number-format-exception查询标签用途Missing catch of NumberFormatExceptionjava/uncaught-number-format-exceptionreliability, external/cwe/cwe-248找出调用Integer.parseInt及类似字符串转数字方法、却缺少对应catch子句的位置结果默认在 LGTM 上隐藏4.1 问题背景Integer.parseInt等解析方法在参数无法解析时会抛出NumberFormatExceptionCWE-248未捕获的异常若调用处没有catch处理解析失败将导致运行时异常冒泡轻则中断业务逻辑重则引发可用性问题。4.2 不安全 / 安全写法对照仓库示例 java/ql/src/Violations of Best Practice/Exception Handling/NumberFormatException.javaString s ...; int n; n Integer.parseInt(s); // BAD: NumberFormatException is not caught. try { n Integer.parseInt(s); } catch (NumberFormatException e) { // GOOD: The exception is caught. // Handle the exception }qhelp java/ql/src/Violations of Best Practice/Exception Handling/NumberFormatException.qhelp 的建议是最好在调用解析方法的周围用catch子句处理NumberFormatException。4.3 查询实现逻辑查询文件 java/ql/src/Violations of Best Practice/Exception Handling/NumberFormatException.ql 的判定条件为from Expr e where throwsNfe(e) and not exists(TryStmt t | t.getBlock() e.getEnclosingStmt().getEnclosingStmt*() and catchesNfe(t) ) and not exists(Callable c | e.getEnclosingCallable() c and c.getAThrownExceptionType().getADescendant() instanceof NumberFormatException ) select e, Potential uncaught java.lang.NumberFormatException.即满足三条件才告警① 表达式e会抛出 NFEthrowsNfe由 semmle.code.java.NumberFormatException 库定义哪些 API 属于字符串转数字② 其外层语句链getEnclosingStmt*上不存在捕获 NFE 的try③ 所在方法未在声明中抛出其子类型异常。元数据标注problem.severity recommendation建议级与precision high因此该查询默认在 LGTM 上隐藏属于低噪声、按需开启的可靠性类查询。五、既有查询变更SQL 注入检测能力大幅扩展发布说明中涉及两项 SQL 注入相关查询查询预期影响变更内容Query built from user-controlled sourcesjava/sql-injection更多结果新增 Spring JDBC、MyBatis、Hibernate 框架的 SQL 注入 sinkQuery built without neutralizing special charactersjava/concatenated-sql-query更多结果同上sink 集合同步扩展5.1 扩展的框架与 sink 模型Spring JDBCJdbcTemplate等执行原生 SQL 的 APIMyBatis注解式Select等与 Mapper XML 中的 SQL 语句构建HibernateHQL/原生查询 API。5.2 源码佐证统一的 QueryInjection 框架两条查询共享同一套底层污点框架。核心库 java/ql/lib/semmle/code/java/security/QueryInjection.qll 中定义/** A sink for database query language injection vulnerabilities. */ abstract class QueryInjectionSink extends ApiSinkNode { } /** A sink for SQL injection vulnerabilities. */ private class SqlInjectionSink extends QueryInjectionSink { SqlInjectionSink() { sinkNode(this, sql-injection) } } ... private class MyBatisSqlInjectionSink extends QueryInjectionSink instanceof MyBatisInjectionSink { }sinkNode(this, sql-injection)通过 ExternalFlow 模型external/codeql-data-flow之类的数据驱动模型为 Spring JDBC、Hibernate 等声明 sinkMyBatis 则通过专门的MyBatisInjectionSink类见 java/ql/lib/semmle/code/java/frameworks/MyBatis.qll、java/ql/lib/semmle/code/java/frameworks/Hibernate.qll建模。框架模型一旦扩充java/sql-injection与java/concatenated-sql-query两条查询同时受益这正是发布说明中More results的由来。以java/sql-injection为例java/ql/src/Security/CWE/CWE-089/SqlTainted.ql 将QueryInjectionSink与污点源结合报告所有依赖用户输入的查询构建点from QueryInjectionSink query, QueryInjectionFlow::PathNode source, QueryInjectionFlow::PathNode sink where queryIsTaintedBy(query, source, sink) select query, source, sink, This query depends on a $., source.getNode(), user-provided value配套的拼接类查询见 java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql。5.3 实战提示升级到 1.19 后若项目使用了 Spring JDBC / MyBatis / Hibernate这两条查询会报告更多真实命中建议在 CI 中重新跑一遍java-security-and-quality套件见 java/ql/src/codeql-suites/java-security-and-quality.qls并对新增告警按是否在 SQL 语句中拼接了外部输入进行人工复核。六、既有查询变更误报收敛false positive 修复查询预期影响变更内容Array index out of boundsjava/index-out-of-bounds误报减少数组长度能被 3或更大数整除、且索引以相似步长递增的场景不再报告Confusing overloading of methodsjava/confusing-method-signature误报减少修正继承关系判定消除特定泛型类上的伪结果Unreachable catch clausejava/unreachable-catch-clause误报减少现在能正确处理抛出泛型异常的泛型方法调用Useless comparison testjava/constant-comparison误报减少不再报告用于防护java.util.ConcurrentModificationException的常量比较——这类比较在无 API 误用时本就恒为 false属于有意的防御式写法这四项改进都服务于同一个目标让查询在保持检出率的同时降低告警噪声。java/index-out-of-bounds查询位于 java/ql/src/Likely Bugs/Collections/ArrayIndexOutOfBounds.ql。此前的误报源于对步长与长度同余的边界情形缺乏建模——当长度是步长的整数倍时越界与否取决于最后一次迭代的精确比较旧逻辑会漏掉这一事实java/confusing-method-signature位于 java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql。修复点是继承关系的计算泛型类通过桥接方法/类型参数展开后旧实现可能把不构成重载冲突的签名对误判为混淆重载java/unreachable-catch-clause与java/constant-comparison的修复本质都是让分析器更贴近 Java 语义泛型异常的类型擦除传播、并发修改异常的保护性判断避免把合理防御当成缺陷。七、QL 库变更面向查询作者的 API 调整7.1ControlFlowNode与Expr/Stmt的相等性废弃The classControlFlowNode(and by extensionBasicBlock) has until now been directly equatable toExprandStmt. Exploiting these equalities, for example by using casts, is now deprecated, and the conversionsExpr.getControlFlowNode()andStmt.getControlFlowNode()should be used instead.背景此前ControlFlowNode与Expr、Stmt之间存在直接相等性即同一个 QL 值可能同时是表达式/语句/控制流节点查询作者可以利用强制类型转换cast在两者间互转。这种方式隐式且易错。变更此类转换已标记为废弃deprecated要求显式调用转换方法。现状在当前仓库中java/ql/lib/semmle/code/java/Expr.qll 第 67–70 行仍保留两种取节点的方式BasicBlock getBasicBlock() { result.getANode().asExpr() this } /** Gets the ControlFlowNode corresponding to this expression. */ ControlFlowNode getControlFlowNode() { result.asExpr() this }迁移建议若你的自定义查询中写过e.(ControlFlowNode)这类 cast请改为e.getControlFlowNode()Stmt同理使用Stmt.getControlFlowNode()见 java/ql/lib/semmle/code/java/Statement.qll。该 API 调整也同步影响依赖控制流的库如 Guards.qll、Paths.qll。7.2 默认污点源扩展Spring 注解参数成为远程输入源The default set of taint sources in theFlowSourceslibrary is extended to cover parameters annotated with Spring framework annotations indicating remote user input from servlets. This affects all security queries, which will yield additional results on projects that use the Spring Web framework.影响面所有安全查询的默认源集合同步扩大使用 Spring Web 的项目会得到额外结果。源码佐证污点源定义在 java/ql/lib/semmle/code/java/dataflow/FlowSources.qll它导入 SpringController.qll 与 SpringWeb.qll 等 Spring 框架模型。关键类SpringRequestMappingParameterSpringController.qll把标注了RequestParam、RequestBody、PathVariable、CookieValue、RequestHeader等SpringServletInputAnnotation的控制器方法参数识别为远程输入InputStream/Reader类型的参数可读请求体也归入显式污染输入。实战含义从 1.19 起Spring MVC 控制器的RequestParam String name等参数默认即可作为污点源不必再为这些场景手工添加 source 模型反过来这也意味着安全查询在 Spring 项目上会报告更多告警评审时需结合威胁模型确认。7.3 范围分析升级ParityAnalysis→ModulusAnalysisTheParityAnalysislibrary is replaced with the more generalModulusAnalysislibrary, which improves the range analysis.旧实现ParityAnalysis只跟踪表达式的奇偶性mod 2信息粒度有限。新实现ModulusAnalysis支持任意模数m的同余推理。源码佐证新库位于 java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll文件头注释给出其推理形式Provides inferences of the form:eequalsb vmodulomwhereeis an expression,bis aBound(typically zero or the value of an SSA variable), andvis an integer in the range[0 .. m-1].即推导表达式e在模m下等于某个界b加一个[0..m-1]内的偏移v。库内包含valueFlowStepSsaSSA 值流步骤、nonConstAddition非常量加法识别等谓词并与 RangeAnalysis.qll 协同为越界检查、数组索引分析等提供更精确的整数取值范围。影响受益于模数推理java/index-out-of-bounds等依赖范围分析的查询精度提升自定义查询若要使用同余信息应从semmle.code.java.dataflow.ModulusAnalysis导入。八、迁移与升级检查清单升级到 1.19 并启用新的 Java 分析时建议按以下清单逐项核对查询套件确认java-security-and-quality.qls/java-security-extended.qls已包含新增的java/zipslip默认开启与java/uncaught-number-format-exception默认隐藏如需启用可在套件中显式加入新告警处理重点评审java/sql-injection与java/concatenated-sql-query在 Spring JDBC / MyBatis / Hibernate 项目上的新增结果自定义查询迁移将ControlFlowNode与Expr/Stmt间的 cast 改写为getControlFlowNode()如需奇偶/同余推理改用ModulusAnalysisSpring 项目意识到默认污点源已覆盖 servlet 远程输入注解参数威胁模型可能因此扩大误报回归验证对java/index-out-of-bounds、java/confusing-method-signature、java/unreachable-catch-clause、java/constant-comparison的既有基线做一次比对确认误报确实下降、无有效告警丢失。九、小结CodeQL 1.19 的 Java 分析改进呈现出清晰的演进方向以数据驱动方式持续扩充框架模型SQL sink、Spring 污点源以更精细的数值/继承/异常语义分析降低误报同时推动查询作者走向更显式的 API。对安全工程师而言Zip Slip 查询提供了现成的归档解压漏洞检测能力对查询开发者而言ModulusAnalysis与FlowSources的演进值得深入研读其源码ModulusAnalysis.qll、FlowSources.qll它们代表了 CodeQL Java 库当前的分析能力边界。赞分享静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security项目地址https://gitcode.com/gh_mirrors/co/codeql点击查看免费下载相关推荐CodeQL 1.18 C 分析改进全解新查询、查询重构与 QL 库 API 演进CodeQL 1.18 C 分析改进全解新查询、查询重构与 QL 库 API 演进 导读 本文以 CodeQL 仓库的 change notes/1.18/a静态分析SAST应用安全漏洞扫描代码质量CodeQL 1.20 的 C/C 分析改进详解新查询、查询更新与 QL 库增强CodeQL 1.20 的 C/C 分析改进详解新查询、查询更新与 QL 库增强 本指南基于 CodeQL 仓库中 change notes/1.20/a静态分析SAST应用安全漏洞扫描代码质量CodeQL C/C 1.18 分析能力升级新查询、查询改进与 QL 库变更深度解析CodeQL C/C 1.18 分析能力升级新查询、查询改进与 QL 库变更深度解析 本文对应 CodeQL 仓库 change notes/1.18/a静态分析SAST应用安全漏洞扫描代码质量创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网