Skip to main content

使用 CodeQL 查询分析代码

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

谁可以使用此功能?

GitHub CodeQL 在安装后按用户授权。 根据许可证限制,只能将 CodeQL 用于某些任务。 有关详细信息,请参阅“关于 CodeQL CLI”。

如果你有 GitHub Advanced Security 许可证,则可以使用 CodeQL 进行自动分析、持续集成和持续交付。 有关详细信息,请参阅“关于 GitHub 高级安全性”。

关于使用 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 时,code scanning 使用此类别来分别存储每种语言的结果。 如果忘记执行此操作,则每次上传都会覆盖之前的结果。

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

必须指定 <database>--format--output。 可以指定其他选项,具体取决于要执行的分析。

选项必选使用情况
<database>指定包含要分析的 CodeQL 数据库的目录路径。
<packs,queries>指定要运行 CodeQL 包或查询。 要运行用于 code scanning 的标准查询,请省略此参数。 要查看 CodeQL CLI 捆绑包中包含的其他查询套件,请查看 /<extraction-root>/qlpacks/codeql/<language>-queries/codeql-suites。 有关创建你自己的查询套件的信息,请参阅 CodeQL CLI 文档中的 创建 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(Beta) 用来添加威胁模型,以便在 CodeQL 分析中配置其他来源。 在 beta 期间,威胁模型仅受 Java 分析支持。 有关详细信息,请参阅“数据库分析”。

升级数据库

对于由 CodeQL CLI v2.3.3 或更早版本创建的数据库,需要显式升级数据库,然后才能使用较新版本的 CodeQL CLI 运行分析。 如果此步骤是必需的,则会看到一条消息,告知在运行 database analyze 时需要升级数据库。

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

有关分析数据库时可以使用的所有选项的完整详细信息,请参阅“数据库分析”。

分析 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,以供显示在 code scanning 的 工具状态页 上。 有关文件覆盖率信息的详细信息,请参阅“关于代码扫描的工具状态页”。

若要在 code scanning 结果中包含文件覆盖率信息,请将 --sarif-add-baseline-file-info 标志添加到 CI 系统中的 codeql database analyze 调用,例如:

$ 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 Container registry 运行现有的 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

此命令运行一个简单的查询,用于查找与未使用的变量、导入、函数或类相关的潜在 bug,它是包含在 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 是一个 SemVer 范围

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

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

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

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

若要使用 codeql/cpp-queries CodeQL 包内 experimental/Security 文件夹中的所有查询来分析数据库,可以使用:

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

若要在 codeql/cpp-queries CodeQL 包中运行 RedundantNullCheckParam.ql 查询,请使用:

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

使用 codeql/cpp-queries CodeQL 包版本中的 cpp-security-and-quality.qls 查询套件分析数据库,版本 >= 0.0.3 且 < 0.1.0(将选择最高兼容版本)可以使用:

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-queriesCodeQL 查询包,运行分析,并生成 SARIF 版本 2.1.0 格式的文件,所有版本的 GitHub 都支持该格式的文件。 可通过执行 codeql github upload-results 或代码扫描 API 将此文件上传到 GitHub。 有关详细信息,请参阅“将 CodeQL 分析结果上传到 GitHub”或“适用于代码扫描的 REST API 终结点”。

CodeQL 查询套件是 .qls 文件,它们使用指令来选择要根据某些元数据属性运行的查询。 标准 CodeQL 包具有指定代码扫描使用的查询套件位置的元数据,因此 CodeQL CLI 知道在哪里可以自动找到这些套件文件,并且不必在命令行中指定完整路径。 有关详细信息,请参阅“创建 CodeQL 查询套件”。

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

包含模型包,以添加潜在受污染数据的其他来源

注意: 风险模型功能目前为 beta,可能随时更改。 在 beta 期间,风险模型仅支持 Java/Kotlin 和 C# 分析。

可以在 code scanning 分析中配置威胁模型。 有关更多信息,请参阅 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 输出”。

结果文件可以集成到你自己的代码评审或调试基础结构中。 例如,使用 IDE 的 SARIF 查看器插件,可以使用 SARIF 文件输出在源代码中的正确位置突出显示警报。

查看日志和诊断信息

当您使用 code scanning 查询套件分析 CodeQL 数据库时,除了生成有关警报的详细信息外,CLI 还报告数据库生成步骤和汇总指标的诊断数据。 如果选择生成 SARIF 输出,则附加数据也会包含在 SARIF 文件中。 对于警报很少的存储库,您可能会发现此信息可用于确定代码中是否真的存在很少的问题,或者生成 CodeQL 数据库时是否出错。 要获取 codeql database analyze 更详细的输出,请使用 --verbose 选项。

有关可用诊断信息类型的详细信息,请参阅“查看代码扫描日志”。

即使 CodeQL 分析失败,你也可以选择将诊断信息导出并上传到 GitHub。 有关详细信息,请参阅“将 CodeQL 分析结果上传到 GitHub”。

后续步骤