跳至主要内容

使用 CodeQL 查询分析代码

您可以对从代码库提取的 CodeQL 数据库运行查询。

谁可以使用此功能?

CodeQL 可用于以下仓库类型

关于使用 CodeQL CLI 分析数据库

要分析代码库,您需要对从代码中提取的 CodeQL 数据库运行查询。CodeQL 分析会生成可以上传到 GitHub 的结果,从而生成代码扫描警报。

先决条件

在开始分析之前,您必须

运行 codeql database analyze 最简便的方式是使用 CodeQL CLI 包中包含的标准查询。

运行 codeql database analyze

当您运行 database analyze 时,它

  1. 可选地下载任何本地不可用的引用的 CodeQL 包。
  2. 执行一个或多个查询文件,对 CodeQL 数据库运行它们。
  3. 根据特定查询元数据解释结果,以便在源代码的正确位置显示警报。
  4. 将任何诊断和摘要查询的结果报告到标准输出。

您可以通过运行以下命令来分析数据库

codeql database analyze <database> --format=<format> --output=<output> <query-specifiers>...

注意

如果对同一次提交分析多个 CodeQL 数据库,必须为此命令生成的每一组结果指定一个 SARIF 类别。将结果上传到 GitHub 时,代码扫描会使用该类别将每种语言的结果分别存储。如果忘记指定,每次上传都会覆盖之前的结果。

codeql database analyze <database> --format=<format> \
    --sarif-category=<language-specifier> --output=<output> \
    <packs,queries>

必须同时指定 <database>--format--output。根据您想要执行的分析,还可以指定其他选项。

选项是否必填用途
<database>指定包含要分析的 CodeQL 数据库的目录路径。
<packs,queries>指定要运行的 CodeQL 包或查询。要运行代码扫描使用的标准查询,请省略此参数。要查看 CodeQL CLI 包中包含的其他查询套件,请运行 codeql resolve queries。列出的套件可以带或不带 .qls 扩展名。有关创建自定义查询套件的信息,请参阅 创建 CodeQL 查询套件
--format指定分析期间生成的结果文件的格式。支持多种格式,包括 CSV、SARIF 和图形格式。上传到 GitHub 时应使用:sarif-latest。更多信息请参阅 代码扫描的 SARIF 支持
--output指定要保存 SARIF 结果文件的位置,包括带有 .sarif 扩展名的文件名。
--sarif-category单个数据库分析时可选;对同一次提交分析多个数据库时必须指定,以定义语言。

为此分析的 SARIF 结果文件指定一个类别。类别用于区分针对同一工具和同一次提交、但针对不同语言或代码不同部分的多次分析。
--sarif-add-baseline-file-info推荐。 用于向工具状态页面提交文件覆盖信息。更多信息请参阅 使用工具状态页面进行代码扫描
--sarif-include-query-help指定是否在 SARIF 输出中包含查询帮助。可取值为:always:为所有查询包含帮助;custom_queries_only(默认):仅为自定义查询(即不属于 codeql/<lang>-queries 形式的查询包)包含帮助;never:不为任何查询包含帮助。任何包含在 SARIF 输出中的自定义查询帮助都会在对应的代码扫描警报中显示。更多信息请参阅 为 CodeQL CLI 编写自定义查询
<packs>如果希望在分析中包含 CodeQL 查询包,请使用此选项。更多信息请参阅 下载和使用 CodeQL 包
--download如果某些 CodeQL 查询包尚未在本地,需要在运行查询之前下载,请使用此选项。
--threads如果希望使用多线程运行查询,请使用此选项。默认值为 1。可以指定更多线程以加速查询执行。若希望线程数等于逻辑处理器数,请指定 0
--verbose用于获取关于分析过程以及数据库创建过程的更详细信息和诊断数据。
--threat-model(公开预览) 用于在 CodeQL 分析中添加威胁模型,以配置额外的来源。公开预览期间,威胁模型仅在 Java 分析中受支持。更多信息请参阅 database analyze

注意

升级数据库

对于由 CodeQL CLI v2.3.3 或更早版本创建的数据库,您需要在使用更新版本的 CodeQL CLI 运行分析之前显式升级数据库。如果需要此步骤,当您运行 database analyze 时会看到提示数据库需要升级的消息。

对于由 CodeQL CLI v2.3.4 或更高版本创建的数据库,CLI 会隐式执行任何必需的升级。无需显式运行升级命令。

有关分析数据库时可使用的所有选项的完整细节,请参阅 database analyze

分析 CodeQL 数据库的基本示例

此示例分析位于 /codeql-dbs/example-repo 的 CodeQL 数据库,并将结果保存为 SARIF 文件:/temp/example-repo-js.sarif。它使用 --sarif-category 在 SARIF 文件中加入额外信息,以标识结果属于 JavaScript。这在对同一提交的仓库中分析多个 CodeQL 数据库时是必需的。

$ codeql database analyze /codeql-dbs/example-repo \
    javascript-code-scanning.qls --sarif-category=javascript-typescript \
    --format=sarif-latest --output=/temp/example-repo-js.sarif

> Running queries.
> Compiling query plan for /codeql-home/codeql/qlpacks/codeql-javascript/AngularJS/DisablingSce.ql.
...
> Shutting down query evaluator.
> Interpreting results.

向结果添加文件覆盖信息以进行监控

您可以选择将文件覆盖信息提交到 GitHub,以在代码扫描的工具状态页面上显示。有关文件覆盖信息的更多内容,请参阅 使用工具状态页面进行代码扫描

要在代码扫描结果中包含文件覆盖信息,请在 CI 系统中调用 codeql database analyze 时添加 --sarif-add-baseline-file-info 标志,例如

$ codeql database analyze /codeql-dbs/example-repo \
    javascript-code-scanning.qls --sarif-category=javascript-typescript \
    --sarif-add-baseline-file-info \ --format=sarif-latest \
    --output=/temp/example-repo-js.sarif

运行数据库分析的示例

以下示例展示了如何使用 CodeQL 包运行 database analyze,以及如何使用 CodeQL 仓库的本地检出。这些示例假设您的 CodeQL 数据库已创建于与本地 CodeQL 仓库副本同级的目录中。

运行 CodeQL 查询包

要从 GitHub 容器注册表运行已有的 CodeQL 查询包,可以指定一个或多个包名。

codeql database analyze <database> microsoft/coding-standards@1.0.0 github/security-queries --format=sarifv2.1.0 --output=query-results.sarif --download

此命令在指定的数据库上运行两个 CodeQL 查询包的默认查询套件:microsoft/coding-standards(版本 1.0.0)和 github/security-queries 的最新版本。如需进一步了解默认套件,请参阅 发布和使用 CodeQL 包

--download 标志是可选的。使用它可确保在本地尚未拥有该查询包时进行下载。

运行单个查询

要在 JavaScript 代码库的 CodeQL 数据库上运行单个查询,可在包含数据库的目录中使用以下命令:

codeql database analyze --download <javascript-database> codeql/javascript-queries:Declarations/UnusedVariable.ql --format=csv --output=js-analysis/js-results.csv

此命令运行一个简单查询,查找未使用的变量、导入、函数或类等潜在错误——该查询是 CodeQL 仓库中包含的 JavaScript 查询之一。您可以通过空格分隔的路径列表一次运行多个查询。

分析会在新目录 (js-analysis) 中生成一个 CSV 文件 (js-results.csv)。

另外,如果您已检出 CodeQL 仓库,也可以通过直接指定查询路径来执行相同的查询。

codeql database analyze <javascript-database> ../ql/javascript/ql/src/Declarations/UnusedVariable.ql --format=csv --output=js-analysis/js-results.csv

您还可以使用 database analyze 命令运行自己的自定义查询。有关准备查询以供 CodeQL CLI 使用的更多信息,请参阅 为 CodeQL CLI 编写自定义查询

运行目录中的所有查询

通过提供目录路径(而不是列出所有单独的查询文件),您可以运行目录中所有查询。路径会递归搜索,因此子文件夹中的查询也会被执行。

重要提示

执行 database analyze 时,最好避免指定核心 CodeQL 查询包的根目录,因为其中可能包含一些不适合该命令使用的特殊查询。相反,请运行查询包本身以在分析中包含该包的默认查询,或使用代码扫描查询套件。

例如,要执行 codeql/python-queries 查询包中 Functions 目录下的所有 Python 查询,可运行

codeql database analyze <python-database> codeql/python-queries:Functions --format=sarif-latest --output=python-analysis/python-results.sarif --download

另外,如果您已检出 CodeQL 仓库,也可以直接指定目录路径来执行相同的查询。

codeql database analyze <python-database> ../ql/python/ql/src/Functions/ --format=sarif-latest --output=python-analysis/python-results.sarif

分析完成后,会生成 SARIF 结果文件。指定 --format=sarif-latest 可确保结果按照 CodeQL 支持的最新 SARIF 规范进行格式化。

在 CodeQL 包中运行查询子集

如果您使用的是 CodeQL CLI v2.8.1 或更高版本,可以在包规范的末尾添加路径,以运行该包内部的查询子集。这适用于所有在包内定位或运行查询的命令。

完整的查询集指定方式为 scope/name@range:path,其中

  • scope/name 是 CodeQL 包的限定名称。

  • range 是一个 语义化版本范围

  • path 是指向单个查询、包含查询的目录或查询套件文件的文件系统路径。

当您指定 scope/name 时,rangepath 均为可选。若省略 range,则使用指定包的最新版本。若省略 path,则使用该包的默认查询套件。

path 可以是 *.ql 查询文件、包含一个或多个查询的目录,或 .qls 查询套件文件。如果省略包名,则必须提供 path,该路径相对于当前进程的工作目录进行解析。

如果同时指定了 scope/namepath,则 path 不能是绝对路径。它被视为相对于 CodeQL 包根目录的相对路径。

要使用 codeql/cpp-queries 包中 experimental/Security 文件夹下的所有查询分析数据库,可使用

codeql database analyze --format=sarif-latest --output=results <db> \
    codeql/cpp-queries:experimental/Security

要在 codeql/cpp-queries 包中运行 RedundantNullCheckParam.ql 查询,可使用

codeql database analyze --format=sarif-latest --output=results <db> \
    'codeql/cpp-queries:experimental/Likely Bugs/RedundantNullCheckParam.ql'

要使用版本在 ≥ 0.0.3 且 < 0.1.0 之间(将自动选择最高兼容版本)的 codeql/cpp-queries 包中的 cpp-security-and-quality.qls 查询套件分析数据库,可使用

codeql database analyze --format=sarif-latest --output=results <db> \
   'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls'

如果需要引用的查询文件、目录或套件路径中包含字面量 @:,可以在查询规范前加上前缀 path:,例如

codeql database analyze --format=sarif-latest --output=results <db> \
    path:C:/Users/ci/workspace@2/security/query.ql

有关 CodeQL 包的更多信息,请参阅 使用 CodeQL 包自定义分析

运行查询套件

要在 C/C++ 代码库的 CodeQL 数据库上运行查询套件,可在包含数据库的目录中使用以下命令:

codeql database analyze <cpp-database> codeql/cpp-queries:codeql-suites/cpp-code-scanning.qls --format=sarifv2.1.0 --output=cpp-results.sarif --download

此命令会下载 codeql/cpp-queries CodeQL 查询包,执行分析,并生成符合所有 GitHub 版本支持的 SARIF 2.1.0 格式文件。可以通过执行 codeql github upload-results 或调用代码扫描 API 将该文件上传到 GitHub。更多信息请参阅 将 CodeQL 分析结果上传到 GitHub代码扫描的 REST API 端点

CodeQL 查询套件是使用指令选择基于特定元数据属性的查询的 .qls 文件。标准 CodeQL 包的元数据指定了代码扫描使用的查询套件位置,因而 CodeQL CLI 能自动找到这些套件文件,您无需在命令行中提供完整路径。更多信息请参阅 创建 CodeQL 查询套件

有关创建自定义查询套件的信息,请参阅 创建 CodeQL 查询套件

包括模型包以添加潜在的污点数据来源

注意

威胁模型目前处于公开预览阶段,可能会更改。在公开预览期间,威胁模型仅在针对 Java/Kotlin 和 C# 的分析中受支持。

您可以在代码扫描分析中配置威胁模型。更多信息请参阅 CodeQL 文档中的 Java 与 Kotlin 的威胁模型C# 的威胁模型

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

在本示例中,标准查询包 codeql/java-queries 中的相关查询将使用 local 威胁模型以及默认的 remote 数据流来源模型。如果您认为本地来源(例如文件系统、命令行参数、数据库和环境变量)可能是代码库的污点数据来源,则应使用 local 威胁模型。

结果

您可以将分析结果保存为多种格式,包括 SARIF 和 CSV。

SARIF 格式旨在表示广泛的静态分析工具的输出。更多信息请参阅 CodeQL CLI SARIF 输出

有关 CSV 格式结果的详细信息,请参阅 CodeQL CLI CSV 输出

结果文件可以集成到您自己的代码审查或调试基础设施中。例如,使用 SARIF 查看器插件可以在 IDE 中将警报高亮显示在源代码的正确位置。

查看日志和诊断信息

当您使用代码扫描查询套件分析 CodeQL 数据库时,除了生成关于警报的详细信息外,CLI 还会报告数据库生成步骤的诊断数据和摘要指标。如果您选择生成 SARIF 输出,这些附加数据也会包含在 SARIF 文件中。对于警报较少的仓库,此信息有助于判断代码是否真的问题不多,还是在生成 CodeQL 数据库时出现错误。若需获取 codeql database analyze 的更详细输出,请使用 --verbose 选项。

关于可用诊断信息类型的更多信息,请参阅 代码扫描日志

即使 CodeQL 分析失败,您也可以选择导出并上传诊断信息到 GitHub。更多信息请参阅 如果分析失败,将诊断信息上传到 GitHub

后续步骤

© . This site is unofficial and not affiliated with GitHub, Inc.