资讯中心

CodeQL C 分析器 1.21 版本更新详解:C 8 特性提取与 QL 库建模

📅 2026/9/27 10:13:31
CodeQL C 分析器 1.21 版本更新详解:C 8 特性提取与 QL 库建模
静态分析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.21/analysis-csharp.md 的变更记录系统梳理 1.21 版本中 C# 分析器的全部能力升级C# 8 语言特性的提取与分析支持、两条新增安全/并发查询、三条既有查询的误报率改进以及 QL 库中针对属性、类型参数约束、模式匹配与 switch 表达式的新增建模类。读完本文你将掌握这些新特性对应的 QL 类、谓词与测试用例的位置能够直接在仓库中定位实现细节并在自己的 CodeQL 查询中正确使用这些新 API。1. 版本总览C# 8 全量支持1.21 版本的 C# 分析器对 C# 8 特性实现了从提取器extractor到 QL 库的全链路支持既有 5 项语法特性进入代码提取流程同时 QL 库中新增 10 余个建模类与多个新谓词还在此基础上发布了 2 条新查询并优化了 3 条既有查询。这意味着此前无法被分析器识别的 C# 8 语法在本版本中已可以被正确解析、建模并参与数据流与污点分析。2. 新增查询1.21 版本新增了一条面向并发与安全的告警查询查询标签目的线程不安全地捕获 ICryptoTransform 对象cs/thread-unsafe-icryptotransform-captured-in-lambdaconcurrency、security、external/cwe/cwe-362标记一类实例其字段类型为System.Security.Cryptography.ICryptoTransform该实例被 lambda 捕获且出现在疑似线程初始化方法中。默认情况下该查询结果不会在 LGTM 上展示这条查询对应仓库中的 ThreadUnsafeICryptoTransformLambda.ql。从源码可以看到它的实现思路import semmle.code.csharp.security.dataflow.flowsinks.ParallelSink import ICryptoTransform module NotThreadSafeCryptoUsageIntoParallelInvokeConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof LambdaCapturingICryptoTransformSource } predicate isSink(DataFlow::Node sink) { sink instanceof ParallelSink } ... }它基于数据流配置DataFlow::ConfigSig实现以捕获了ICryptoTransform类型对象或包含该类字段的 lambda为源source以并行执行入口ParallelSink为汇sink从而识别出对象被 lambda 捕获并在疑似线程初始化方法中使用的危险模式。其告警消息明确指出在并发线程中使用ICryptoTransform实例不仅可能产生错误某些情况下还会导致计算结果不正确这正是 CWE-362TOCTOU 竞态类问题的典型场景。3. 既有查询的改进1.21 版本对三条既有查询做了针对性优化核心目标是降低误报率查询预期影响变更内容常量条件cs/constant-condition更少的误报现在忽略null值出现在空合并表达式左侧条件表达式中的代码。例如(a ? b : null) ?? c中null不再被视为常量条件线程不安全地使用静态 ICryptoTransform 字段cs/thread-unsafe-icryptotransform-field-in-class更少的误报结果判定标准更新新增嵌套属性、嵌套字段与集合的判定告警消息格式调整为突出静态字段查询名称同步更新无用的向上转换cs/useless-upcast更少的误报现在忽略用于消歧构造函数调用目标的向上转换3.1 常量条件空合并语境下的 null 豁免查询实现位于 ConstantCondition.ql。其nullCheck谓词通过NullCoalescingOperation追踪空合并运算predicate nullCheck(Expr e, boolean direct) { exists(QualifiableExpr qe | qe.isConditional() and direct true | ...) or exists(NullCoalescingOperation nce | nce.getLeftOperand() e and direct true) or exists(ConditionalExpr ce | ce.getThen() e or ce.getElse() e | nullCheck(ce, _) and direct false ) }当null位于(a ? b : null) ?? c这类条件表达式中时它只是被合并的候选值而非真正的常量条件因此被豁免从而消除此类误报。3.2 静态 ICryptoTransform 字段判定标准扩展实现位于 ThreadUnsafeICryptoTransform.ql。新版本中UsesICryptoTransform类递归地判定直接或间接使用ICryptoTransform的类型class UsesICryptoTransform extends ValueOrRefType { UsesICryptoTransform() { this instanceof ICryptoTransform or this.getAField().getType() instanceof UsesICryptoTransform or this.getAProperty().getType() instanceof UsesICryptoTransform or getAnEnumeratedType(this) instanceof UsesICryptoTransform } }其中getAnEnumeratedType会遍历类型实现的IEnumerableT泛型接口并取出类型实参实现对集合的判定getAField/getAProperty的递归组合则覆盖了嵌套字段与嵌套属性。同时UnsafeField要求字段为静态isStatic()且未标记ThreadStaticAttribute告警消息改为高亮静态字段本身。3.3 无用的向上转换构造函数消歧豁免实现位于 UselessUpcast.ql。源码中定义了isDisambiguatingConstructorCall谓词UselessUpcast.ql专门识别向上转换被用作构造函数调用实参、以帮助重载决议选择正确构造函数的情形private predicate isDisambiguatingConstructorCall(Constructor other, int args) { exists(ConstructorCall cc, Constructor target, ValueOrRefType t | this.isArgument(cc, target) | ... ) }这类向上转换虽然形式上多余但实际上承担了消歧职责因此在新版本中被排除在告警之外。4. 代码提取的变更1.21 版本的提取器csharp/extractor新增了对以下 C# 8 特性的提取支持范围表达式Range expressions如1..^1递归模式Recursive patterns使用声明语句Using declaration statements局部函数上的static修饰符空合并赋值表达式Null-coalescing assignment expressionsunmanaged类型参数约束提取器的实现可从 Factory.cs 看到SyntaxKind.RangeExpression与SyntaxKind.IndexExpression分别被分派到RangeExpression.Create与IndexExpression的处理逻辑范围表达式的切片语义则在 ElementAccess.cs 中通过RangeExpressionSyntax识别并调用对应的切片方法如string.AsSpan完成建模。测试覆盖同样完备仓库的 csharp/ql/test/library-tests/csharp8 目录下提供了ranges.cs、patterns.cs、UsingDeclarations.cs、NullCoalescingAssignment.cs、StaticLocalFunctions.cs、UnmanagedGenericStructs.cs等测试文件及对应.expected结果文件。例如在 PrintAst.expected 中可以看到提取结果的实证# 8| 0: [AssignCoalesceExpr] ... ?? ... # 8| 0: [UsingDeclStmt] using ... ...; # 13| 1: [RecursivePatternExpr] { ... }5. QL 库的变更5.1 属性类新增两个谓词Attribute.qll 中的Attribute类新增getConstructorArgument(int i)返回特性构造函数调用的实参。例如在MyAttribute[true, Foo 0]中只有true是构造函数实参getNamedArgument(string name)返回用于初始化字段/属性的命名实参。例如上例中Foo 0的0。这两个谓词在库内已有实际使用例如 CodeAnalysis.qll 通过getConstructorArgument(0).getValue()读取CallerMemberName等特性的构造实参。5.2 类型参数约束新增unmanaged判定Generics.qll 中TypeParameterConstraints类新增谓词hasUnmanagedTypeConstraint()用于判断类型参数是否带有unmanaged约束与已有的hasValueTypeConstraint、hasRefTypeConstraint等谓词并列内部通过general_type_parameter_constraints(this, 4)实现。测试用例见 UnmanagedGenericStructs.cs。5.3 C# 8 特性建模类一览QL 库针对 C# 8 新增了以下建模类主要位于 Expr.qll 与 Stmt.qllQL 类建模的 C# 8 语法源码位置AssignCoalesceExpr空合并赋值x ?? yAssignment.qllIndexExpr末尾索引表达式^1Expr.qllRangeExpr范围表达式1..^1Expr.qllPatternExpr及其子类模式表达式详见 5.4 节Expr.qllPatternMatch及子类Case、IsExpr模式匹配Expr.qllSwitchExprswitch 表达式Expr.qllSwitchCaseExprswitch 表达式的分支arm如(false, false) trueExpr.qllSwitch同时建模SwitchExpr与SwitchStmtExpr.qllCase同时建模CaseStmt与SwitchCaseExprExpr.qllUsingStmt同时建模UsingBlockStmt与UsingDeclStmtStmt.qll这里有几个值得注意的设计点AssignCoalesceExpr同时继承AssignOperation与NullCoalescingOperationAssignment.qll因此它既能被赋值相关逻辑识别也能被空合并相关逻辑如 3.1 节的NullCoalescingOperation识别IndexExpr.getExpr()返回^之后的子表达式toString()为^...Expr.qllRangeExpr提供getStart()/getEnd()/hasStart()/hasEnd()谓词覆盖1..3、1..^1、3..、..、..5、..^1等全部六种书写形式Expr.qllSwitchExpr的getCase(int n)/getACase()返回SwitchCaseExprSwitchCaseExpr则通过getPattern()、getCondition()when子句、getBody()右侧结果分别暴露分支的三个组成部分Expr.qll。5.4 模式表达式类族详解PatternExpr是出现在模式中的表达式的基类Expr.qll通过getPatternMatch()可回溯其所属的模式匹配。1.21 版本为它引入了六个新子类子类建模的语法示例DiscardPatternExpr弃元模式x is (_, false)中的_LabeledPatternExpr属性模式中的带标签模式{ Length: 5 }中的Length: 5RecursivePatternExpr递归模式x is string { Length: 5 } sTypeAccessPatternExpr类型访问模式x is string中的stringTypePatternExpr类型模式x is string sVariablePatternExpr变量声明模式x is string s中的s同时新增两个模式匹配建模类PatternMatch模式被匹配的抽象子类为Case与IsExprIsExpris表达式如x is stringExpr.qll。此外PositionalPatternExpr位置模式(int x, int y)Expr.qll与PropertyPatternExpr属性模式Length: int lenExpr.qll也一并加入。其中RecursivePatternExpr提供了组合访问能力getPositionalPatterns()、getPropertyPatterns()、getTypeAccess()、getVariableDeclExpr()分别对应递归模式中的位置模式、属性模式、类型访问与绑定变量Expr.qll可直接用于编写针对复杂模式匹配的分析查询。5.5 废弃与合并与新增类同步库中还完成了一组 API 整合IsConstantExpr、IsTypeExpr、IsPatternExpr三个旧类被废弃统一由IsExpr取代Switch同时建模SwitchExpr与SwitchStmt避免对两种 switch 形式分别建模Case同时建模CaseStmt与SwitchCaseExprUsingStmt同时建模UsingBlockStmt与UsingDeclStmt后者是 C# 8 的 using 声明语句见 Stmt.qll。这种向上合并的设计意味着凡是只关心 switch 语义、case 语义或 using 语义的查询现在只需针对Switch/Case/UsingStmt编写一次即可同时覆盖语句与表达式两种形态。6. 测试与验证仓库为本次更新提供了完整的测试支撑主要集中在两个位置csharp/ql/test/library-tests/csharp8覆盖 C# 8 特性的库测试。其中ranges.ql/ranges.expected验证范围表达式patterns.ql/patterns.expected验证各类模式表达式NullCoalescingAssignment.ql验证空合并赋值UsingDeclarations.ql与UsingControlFlow.ql验证 using 声明语句及控制流StaticLocalFunctions.ql与UnmanagedGenericStructs.ql验证静态局部函数与unmanaged约束switchCaseExprTypes.ql、switchexprcontrolflow.ql验证 switch 表达式及控制流csharp/ql/test/library-tests/controlflow/graph/Dominance.expected 等控制流测试中也包含了新语法节点参与支配分析的结果。读者可直接运行codeql test run csharp/ql/test/library-tests/csharp8复现这些测试或通过.expected文件对照检查自己的查询输出格式。7. 小结1.21 版本是 CodeQL C# 分析器对 C# 8 的完整拥抱提取器覆盖了范围表达式、递归模式、using 声明、静态局部函数、空合并赋值与unmanaged约束六项语法能力QL 库以PatternExpr、SwitchExpr、RangeExpr、AssignCoalesceExpr、UsingStmt等新类完成语义建模并同步废弃合并了旧 API查询层面新增了针对 ICryptoTransform 并发误用的安全查询同时降低了常量条件、静态 ICryptoTransform 字段与无用向上转换三条查询的误报率。对于需要分析现代 C# 代码库的安全研究人员这意味着可以信任 CodeQL 对 C# 8 语法的 AST 与数据流分析结果并直接借助getConstructorArgument、hasUnmanagedTypeConstraint、PatternExpr子类等新 API 编写更精准的自定义查询。赞分享静态分析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.21 C/C 分析改进全解新增安全查询、既有查询强化与 QL 库 API 更新CodeQL 1.21 C/C 分析改进全解新增安全查询、既有查询强化与 QL 库 API 更新 本文以 CodeQL 仓库 change notes/1静态分析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应用安全漏洞扫描代码质量上一篇如何通过TQVaultAE实现泰坦之旅周年版的无限仓库智能管理下一篇抖音批量下载终极方案告别手动保存一键获取完整合集创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案