注意
CodeQL 模型包目前处于公开预览阶段,可能会更改。模型包支持 C/C++、C#、Java/Kotlin、Python、Ruby 和 Rust 的分析。
Visual Studio Code 的 CodeQL 扩展中的 CodeQL 模型编辑器支持对 C#、Java/Kotlin、Python 和 Ruby 的依赖建模。
关于 CodeQL 模型编辑器
使用 CodeQL 模型包,您可以扩展 CodeQL 代码扫描分析的范围,以识别代码库中使用的、默认情况下不受支持的自定义库和框架。借助 CodeQL 模型编辑器,您可以创建自己的模型包。模型编辑器会引导您对应用程序中的外部依赖调用进行建模,或对外部依赖的所有公共入口和退出点进行完整建模。
有关使用模型包自定义代码扫描分析的更多信息,请参阅 编辑默认设置的配置 和 代码扫描的工作流配置选项。
打开模型编辑器后,它会分析当前选中的 CodeQL 数据库,并确定应用程序使用了哪些外部 API 以及所有公共方法。外部(或第三方)API 指的是不属于您所选 CodeQL 数据库的任何 API。
模型编辑器有两种不同的模式
-
应用模式(默认视图):编辑器列出选定 CodeQL 数据库使用的每个外部框架。展开框架后,会显示所有对外部 API 的调用列表,并提供针对每个调用建模数据流的选项。此模式最适合用于提升特定代码库的 CodeQL 结果的精准度。
-
依赖模式:编辑器识别选定 CodeQL 数据库中所有可公开访问的 API。此视图会引导您对代码库提供的每个公共 API 进行建模。完成整个 API 的建模后,您可以保存模型,并将其用于提升所有使用该依赖项的代码库的 CodeQL 分析效果。
本文其余部分介绍使用 CodeQL 模型编辑器对依赖项进行建模的实用方法。技术细节请参阅 CodeQL 语言文档中的 Java 与 Kotlin 的库模型自定义、Python 的库模型自定义、Ruby 的库模型自定义 和 C# 的库模型自定义。
显示 CodeQL 模型编辑器
注意
要使用此公共预览功能,请为 Visual Studio Code 安装最新版本的 CodeQL 扩展。
-
在 VS Code 中打开您的 CodeQL 工作区。例如,
vscode-codeql-starter工作区。如果使用该入门工作区,请将ql子模块从main更新,以确保拥有用于模型编辑器收集数据的查询。 -
在 Visual Studio Code 中,点击左侧边栏的 QL 以显示 CodeQL 扩展。
-
在 “Databases” 视图中,选择您想要建模的 CodeQL 数据库。
-
在 CodeQL “Method Modeling” 视图中,点击 Start modeling 以显示模型编辑器。或者,使用 VS Code 命令面板运行 CodeQL: Open Model Editor (Beta) 命令。
-
CodeQL 模型编辑器会运行一系列遥测查询来识别代码中的 API,并在新标签页中显示编辑器界面。
-
遥测查询完成后,已识别的 API 将显示在编辑器中。
提示
如果在建模调用或方法时需要更多空间,可将 CodeQL “Method Modeling” 视图从主侧边栏移动到次侧边栏。关闭视图后,可通过 VS Code 的 “View” 菜单并点击 Open View... 重新打开。
对代码库调用外部 API 的建模
当您想提升特定代码库的 CodeQL 结果精准度时,通常采用此方法。如果代码库使用的框架或库未被 CodeQL 默认支持,且该框架或库的源代码未纳入分析,这种方式尤为有用。
本节以开源 Java 项目 “sofa-jraft” 为例。对用其他编译语言编写的外部 API 进行建模的体验类似。
-
在 Visual Studio Code 中,选择您希望提升 CodeQL 覆盖率的 CodeQL 数据库。
-
显示 CodeQL 模型编辑器。默认情况下,编辑器以应用模式运行,因而会显示所选代码库使用的外部 API 列表。

-
点击展开某个外部 API,以查看从代码库到该外部依赖的调用列表。

-
点击与 API 调用或方法关联的 View,即可查看其在代码库中的使用位置。
-
包含首次从代码库调用该 API 的文件会被打开,并在 VS Code 中显示 CodeQL “Methods Usage” 视图(通常与 “Problems” 与 “Terminal” 视图共存)。该视图按方法分组列出所有对该 API 的调用,您可以逐一点击以决定如何对该方法进行建模。
-
确定了该方法的建模方式后,可在 CodeQL 扩展的 “Method Modeling” 视图中点击 “Model Type” 下拉框选择不同的模型类型。此更改会自动反映在主模型编辑器中。
-
该行其余字段会根据所选模型类型自动更新为可用选项。
- “Source”:选择要建模的 “Output” 元素。
- “Sink”:选择要建模的 “Input” 元素。
- “Flow summary”:选择要建模的 “Input” 与 “Output” 元素。
-
为模型定义数据流的 “Kind”。
-
建模完成后,返回主模型编辑器并点击每个已展开方法列表右下角的 Save all 或 Save。编辑器中已建模的方法百分比会相应更新。
模型会存放在工作区的 .github/codeql/extensions/CODEQL-MODEL-PACK 目录下,其中 CODEQL-MODEL-PACK 为您所选 CodeQL 数据库的名称,即仓库名 + 连字符 + CodeQL 分析的语言。更多信息请参阅 创建和使用 CodeQL 包。
模型以一系列 YAML 数据扩展文件的形式存储,每个外部 API 对应一个文件。例如:
.github/codeql/extensions/sofa-jraft-java # the model pack directory
models
jmh-core.model.yml # models calls to jmh-core@1.20
rocksdbjni.model.yml # models calls to rocksdbjni@7.7.3
对代码库公共 API 的建模
当您希望为组织中多个代码库共用的框架或库建模时,通常使用此方法。完成模型的创建与测试后,您可以将 CodeQL 模型包发布到 GitHub Container Registry,供整个组织使用。
本节以开源 Java 项目 “sofa-jraft” 为例。对用其他编译语言编写的外部 API 进行建模的体验类似。
-
选择您想要建模的 CodeQL 数据库。
-
显示 CodeQL 模型编辑器。默认情况下编辑器在应用模式下运行。点击 Model as dependency 切换到依赖模式,屏幕会切换为显示框架或库的公共 API。

-
点击展开某个包,以查看可用方法列表。
-
点击与方法关联的 View 可查看其定义。

-
确定了方法的建模方式后,定义 “Model type”。
-
该行其余字段会根据所选模型类型自动更新为可用选项。
- “Source”:选择要建模的 “Output” 元素。
- “Sink”:选择要建模的 “Input” 元素。
- “Flow summary”:选择要建模的 “Input” 与 “Output” 元素。
-
为模型定义数据流的 “Kind”。
-
建模完成后,点击每个已展开调用列表右下角的 Save all 或 Save。编辑器中已建模的调用百分比会相应更新。
模型会存放在工作区的 .github/codeql/extensions/CODEQL-MODEL-PACK 目录下,其中 CODEQL-MODEL-PACK 为您所选 CodeQL 数据库的名称,即仓库名 + 连字符 + CodeQL 分析的语言。更多信息请参阅 创建和使用 CodeQL 包。
模型以一系列 YAML 数据扩展文件的形式存储,每个公共方法对应一个文件。例如:
.github/codeql/extensions/sofa-jraft-java # the model pack directory
models
com.alipay.sofa.jraft.option.model.yml # models public methods in package
com.alipay.sofa.jraft.rhea.options.model.yml
编辑器会为您建模的每个包生成一个独立的模型文件。
对具有多种潜在流的方法进行建模
某些方法支持多条数据流。务必为方法建模所有数据流,否则无法检测到使用该方法时的所有潜在问题。首先为方法建模一个数据流,然后使用该方法行中的 + 按钮添加第二个数据流模型。

在 VS Code 中测试 CodeQL 模型包
您可以使用 “Running Queries: Use Extension Packs” 设置在 VS Code 中测试任意创建的 CodeQL 模型包。更多信息请参阅 自定义设置。此方法适用于数据库和变体分析仓库。
-
若要在包含于工作区
.github/codeql/extensions目录下的模型包的情况下运行查询,请在settings.json中加入:"codeQL.runningQueries.useExtensionPacks": "all", -
若要在运行查询时不使用模型包,请在
settings.json中加入:"codeQL.runningQueries.useExtensionPacks": "none",
如果模型工作正常,您应能看到两次运行结果的差异。如果未看到任何差异,可能需要引入已知的 bug 以验证模型行为符合预期。