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/[email protected]
> Installed fresh octo-org/[email protected]
> 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/[email protected] - 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/[email protected]:Functions - codeql/python-queries 包版本 1.2.3 中 Functions 目录中的所有查询。

  • codeql/[email protected]: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 文件中的修改生效。