Skip to main content

使用 CodeQL 包自定义分析

可使用 CodeQL 包来运行由其他人维护的 CodeQL 查询,或共享你开发的 CodeQL 查询。

谁可以使用此功能?

CodeQL 可用于以下存储库类型:

关于 CodeQL 包

CodeQL 包用于创建、共享、依赖和运行 CodeQL 查询和库。 CodeQL 包中具有查询、库文件、查询套件和元数据。 可以通过下载其他人创建的包并在代码库上运行这些包来自定义 CodeQL 分析。

有三种类型的 CodeQL 包:查询包、库包和模型包。

  • 查询包包含一组预编译的查询,这些查询可在 CodeQL 数据库上进行评估。 查询包专为运行设计。 发布查询包时,除了查询源外,捆绑包还包括每个查询的所有可传递依赖项和预编译表示形式。 这可确保一致且高效地执行包中的查询。

  • 库包旨在供查询包(或其他库包)使用,并且不包含查询本身。 这些库不是单独编译的。

  • 模型包可用于扩展 code scanning 分析,以识别默认情况下不支持的库和框架。 模型包目前为 公共预览版,可能会更改。 在 公共预览版 期间,模型包可用于 C#、Java/Kotlin、Python,以及 Ruby 分析。 有关创建自己的模型包的详细信息,请参阅 创建并使用 CodeQL 包

所有受支持语言的标准 CodeQL 包在 Container registry 中发布。 如果使用 CodeQL CLI 捆绑包以标准方式安装 CodeQL CLI,则核心查询包已下载并可供使用。 它们是:

  • codeql/cpp-queries
  • codeql/csharp-queries
  • codeql/go-queries
  • codeql/java-queries
  • codeql/javascript-queries
  • codeql/python-queries
  • codeql/ruby-queries
  • codeql/swift-queries

还可以使用 CodeQL CLI 创建你自己的 CodeQL 包、向包添加依赖项以及安装或更新依赖项。 有关详细信息,请参阅“创建并使用 CodeQL 包”。

可以使用 CodeQL CLI 发布已创建的 CodeQL 包。 有关发布和下载 CodeQL 包的详细信息,请参阅 发布及使用 CodeQL 包

下载和使用 CodeQL 查询包

CodeQL CLI 捆绑包中包括由 GitHub 专家、安全研究人员和社区贡献者维护的查询。 如果要运行其他组织开发的查询,CodeQL 查询包提供了一种高效、可靠的方法来下载和运行查询,而模型包 (公共预览版) 可用于扩展 code scanning 分析,以识别默认不支持的库和框架。 有关查询包的详细信息,请参阅 关于使用 CodeQL 进行代码扫描。 有关编写自己的模型包的信息,请参阅 创建并使用 CodeQL 包

在使用 CodeQL 查询包分析数据库之前,必须从 GitHub Container registry 下载所需的任何包。 这可以通过使用 --download 标志作为 codeql database analyze 命令的一部分或运行 codeql pack download 来完成。 如果包不是公开可用,需要使用 GitHub App 或 personal access token 进行身份验证。 有关详细信息和示例,请参阅 将 CodeQL 分析结果上传到 GitHub

选项必选使用情况
<scope/name@version:path>使用以逗号分隔的列表指定要下载的一个或多个 CodeQL 查询包的作用域和名称。 (可选)包括要下载和解压缩的版本。 默认情况下,将下载此包的最新版本。 (可选)包括要运行的查询、目录或查询套件的路径。 如果未包括路径,则运行此包的默认查询。
--github-auth-stdin通过标准输入,将为对 GitHub 的 REST API 进行身份验证而创建的 GitHub App 或 personal access token 从机密存储库传递给 CLI。 如果命令有权访问使用此令牌设置的 GITHUB_TOKEN 环境变量,则不需要执行此操作。

Note

如果指定要使用的查询包的特定版本,需注意你指定的版本最终可能会变得太旧,导致无法有效使用最新版本的 CodeQL。 为了确保最佳性能,如果需要指定确切的查询包版本,应重新评估每次升级所使用的 CodeQL CLI 时要固定到的版本。

有关包兼容性的详细信息,请参阅 发布及使用 CodeQL 包

下载并使用查询包的基本示例

此示例运行包含 --download 选项的 codeql database analyze 命令来执行以下操作:

  1. 下载最新版本的 octo-org/security-queries 包。
  2. 下载与版本 1.0.1 兼容的 octo-org/optional-security-queries 包版本(在本例中为版本 1.0.2)。 有关 SemVer 兼容性的详细信息,请参阅 npm 的语义化版本范围文档
  3. octo-org/security-queries 中运行所有默认查询。
  4. octo-org/optional-security-queries 中仅运行查询 queries/csrf.ql
$ echo $OCTO-ORG_ACCESS_TOKEN | codeql database analyze --download /codeql-dbs/example-repo \
    octo-org/security-queries \
    octo-org/optional-security-queries@~1.0.1:queries/csrf.ql \
    --format=sarif-latest --output=/temp/example-repo-js.sarif

> Download location: /Users/mona/.codeql/packages
> Installed fresh octo-org/security-queries@1.0.0
> Installed fresh octo-org/optional-security-queries@1.0.2
> Running queries.
> Compiling query plan for /Users/mona/.codeql/packages/octo-org/security-queries/1.0.0/potential-sql-injection.ql.
> [1/2] Found in cache: /Users/mona/.codeql/packages/octo-org/security-queries/1.0.0/potential-sql-injection.ql.
> Starting evaluation of octo-org/security-queries/query1.ql.
> Compiling query plan for /Users/mona/.codeql/packages/octo-org/optional-security-queries/1.0.2/queries/csrf.ql.
> [2/2] Found in cache: /Users/mona/.codeql/packages/octo-org/optional-security-queries/1.0.2/queries/csrf.ql.
> Starting evaluation of octo-org/optional-security-queries/queries/csrf.ql.
> [2/2 eval 694ms] Evaluation done; writing results to octo-org/security-queries/query1.bqrs.
> Shutting down query evaluator.
> Interpreting results.

直接下载 CodeQL 包

如果要在不立即运行 CodeQL 包的情况下进行下载,则可以使用 codeql pack download 命令。 如果要避免在运行 CodeQL 查询时访问 Internet,此选项非常有用。 运行 CodeQL 分析时,可以采用与上一示例相同的方式指定包、版本和路径:

echo $OCTO-ORG_ACCESS_TOKEN | codeql pack download <scope/name@version:path> <scope/name@version:path> ...

从多 GitHub 容器注册表下载 CodeQL 包

如果 CodeQL 包存在于多个容器注册表上,就必须指示 CodeQL CLI 在何处查找每个包。 有关详细信息,请参阅“自定义代码扫描的高级设置”。

指定要在 CodeQL 包中运行的查询

查询说明符由 codeql database analyze 和对一组查询进行操作的其他命令使用。 查询说明符的完整形式为 scope/name@range:path,其中:

  • scope/name 是 CodeQL 包的限定名称。
  • range 是一个 SemVer 范围
  • path 是到单个查询、包含查询的目录或查询套件文件的文件系统路径。

指定 scope/name 时,rangepath 是可选的。 如果省略 range,则使用指定包的最新版本。 如果省略 path,则使用指定包的默认查询套件。

path 可以是以下项之一:.ql 查询文件、包含一个或多个查询的目录或 .qls 查询套件文件。 如果省略包名称,则必须提供 path,它将相对于当前进程的工作目录进行解释。 不支持 glob 模式。

如果同时指定 scope/namepath,则 path 不能为绝对值。 它被视为相对于 CodeQL 包的根。

示例查询说明符

  • codeql/python-queries - 最新版本 codeql/python-queries 包的默认查询套件中的所有查询。

  • codeql/python-queries@1.2.3 - codeql/python-queries 包的版本 1.2.3 的默认查询套件中的所有查询。

  • codeql/python-queries@~1.2.3 - 最新版本 codeql/python-queries 包的默认查询套件中的所有查询 >= 1.2.3 且 < 1.3.0

  • codeql/python-queries:Functions - 最新版本的 codeql/python-queries 包中 Functions 目录中的所有查询。

  • codeql/python-queries@1.2.3:Functions - codeql/python-queries 包版本 1.2.3 中 Functions 目录中的所有查询。

  • codeql/python-queries@1.2.3:codeql-suites/python-code-scanning.qls - codeql/python-queries 包版本 1.2.3 中 codeql-suites/python-code-scanning.qls 目录中的所有查询。

  • suites/my-suite.qls - suites/my-suite.qls 文件中相对于当前工作目录的所有查询。

Tip

标准 CodeQL 查询包的默认查询套件为 codeql-suites/<lang>-code-scanning.qls。 还可以在每个包的 codeql-suites 目录中找到其他几个有用的查询套件。 例如,codeql/cpp-queries 包包含以下查询套件:

  • cpp-code-scanning.qls - C++ 的标准代码扫描查询。 此包的默认查询套件。
  • cpp-security-extended.qls - 来自 C++ 的默认 cpp-code-scanning.qls 套件的查询,以及较低严重性和精度的查询。
  • cpp-security-and-quality.qls - 来自 cpp-security-extended.qls 的查询,以及可维护性和可靠性查询。

可以在 CodeQL 存储库中查看这些查询套件的源。 其他语言的查询套件类似。

使用模型包来分析对自定义依赖项的调用

可以使用 --model-packs 选项,将已发布的模型包包含在 code scanning 分析中。 例如:

$ codeql database analyze /codeql-dbs/my-company --format=sarif-latest \
  --model-packs my-repo/my-java-model-pack \
  --output=/temp/my-company.sarif codeql/java-queries

在此示例中,标准查询包 codeql/java-queries 中的相关查询将使用模型包 my-repo/my-java-model-pack 中的依赖项信息,来检查调用这些依赖项的代码中的漏洞。

可以在分析中指定多个已发布的模型包。

有关编写自己的模型包的详细信息,请参阅 创建并使用 CodeQL 包

关于发布的包

发布包用于分析时,codeql pack createcodeql pack publish 命令会验证内容是否完整,并向其中另外添加一些内容:

  • (对于查询包)它所依赖的每个库包的副本,采用其开发的精确版本。 查询包的用户无需单独下载这些库包。

  • (对于查询包)每个查询的预编译表示形式。 与在每次分析时编译查询的 QL 源相比,执行它们的速度更快。

其中大部分数据位于已发布包中名为 .codeql 的目录中,但预编译查询位于每个查询的 .ql 源旁边带有 .qlx 后缀的文件中。 使用已发布包中的查询分析数据库时,CodeQL 将加载这些文件,而不是 .ql 源。 如果需要修改已发布的包的内容,请务必移除所有 .qlx 文件,因为它们可能会阻止 .ql 文件中的修改生效。