注意:本文已于 2023 年 1 月从 CodeQL 文档网站迁移。
关于使用 CodeQL CLI 分析数据库
若要分析代码库,请对从代码中提取的 CodeQL 数据库运行查询。
CodeQL 分析会生成解释的结果,这些结果可在源代码中显示为警报或路径。
有关编写查询以使用 database analyze
运行的信息,请参阅“将自定义查询用于 CodeQL CLI”。
其他查询运行命令
使用 database analyze
运行的查询具有严格的元数据要求。 还可使用以下管道级子命令执行查询:
-
query run:将输出 BQRS 文件,或将结果表直接输出到命令行。 直接在命令行中查看结果对于使用 CLI 进行迭代查询开发可能很有用。
使用这些命令运行的查询没有相同的元数据要求。
但是,若要保存人类可读数据,必须使用 bqrs 解码 管道子命令处理每个 BQRS 结果文件。 因此,对于大多数用例,使用 database analyze
直接生成解释的结果最简单。
在开始分析之前,必须:
- 设置 CodeQL CLI 以在本地运行命令。
- 为要分析的源代码创建 CodeQL 数据库。
最简单的运行 codeql database analyze
的方法是使用 CodeQL 包。 还可使用 CodeQL 存储库本地签出中的查询运行命令,如果要自定义 CodeQL 核心查询,可能需要执行此操作。
正在运行 codeql database analyze
运行 database analyze
时,其:
- (可选)下载任何引用的 CodeQL 包,这些包在本地不可用。
- 执行一个或多个查询文件,方法是通过 CodeQL 数据库运行它们。
- 根据特定的查询元数据解释结果,以便可以在源代码中的正确位置显示警报。
- 将任何诊断和摘要查询的结果报告给标准输出。
可以通过运行以下命令来分析数据库:
codeql database analyze <database> --format=<format> --output=<output> <query-specifiers>...
必须指定以下内容:
<database>
:要分析的 CodeQL 数据库的路径。--format
:分析期间生成的结果文件的格式。 支持多种不同的格式,包括 CSV、SARIF 和图形格式。 有关 CSV 和 SARIF 的详细信息,请参阅结果。 若要了解支持的其他结果格式,请参阅“数据库分析”。--output
:分析期间生成的结果文件的输出路径。
您还可以指定:
-
<query-specifiers>...
:要对数据库运行的查询的空格分隔列表。 这是一个参数列表,其中每个参数可以是:- 查询文件的路径
- 包含查询文件目录的路径
- 查询套件文件的路径
- CodeQL 查询包的名称
- 具有可选版本范围
- 包含包中查询、目录或查询套件的可选路径
如果省略,将使用已分析数据库语言的默认查询套件。 有关查询说明符的完整语法,请参阅“指定要在 CodeQL 包中运行的查询”。
-
--sarif-category
:结果的标识类别。 当要为提交上传多个结果集时使用。 例如,当使用github upload-results
将多种语言的结果发送到 GitHub 代码扫描 API 时。 有关此用例的详细信息,请参阅在 CI 系统中配置 CodeQL CLI。 -
--sarif-add-query-help
:(从 2.7.1 版本开始支持)将任何用 markdown 编写的自定义查询帮助添加到分析生成的 SARIF 文件(v2.1.0 或更高版本)。 在运行分析之前,必须将存储在.qhelp
文件中的查询帮助转换为.md
。 有关详细信息,请参阅“在 SARIF 文件中包括自定义 CodeQL 查询的查询帮助”。 -
--download
:一个布尔标志,允许 CLI 下载任何引用的 CodeQL 包,这些包在本地不可用。 如果缺少此标志,并且引用的 CodeQL 包在本地不可用,则命令将失败。
升级数据库
对于由 CodeQL CLI v2.3.3 或更早版本创建的数据库,需要显式升级数据库,然后才能使用较新版本的 CodeQL CLI 运行分析。 如果此步骤是必需的,则会看到一条消息,告知在运行 database analyze
时需要升级数据库。
对于由 CodeQL CLI v2.3.4 或更高版本创建的数据库,CLI 将隐式运行任何所需的升级。 无需显式运行升级命令。
有关分析数据库时可以使用的所有选项的完整详细信息,请参阅“数据库分析”。
指定要在 CodeQL 包中运行的查询
查询说明符由 codeql database analyze
和对一组查询进行操作的其他命令使用。
查询说明符的完整形式为 scope/name@range:path
,其中:
-
scope/name
是 CodeQL 包的限定名称。 -
range
是一个 SemVer 范围。 -
path
是到单个查询、包含查询的目录或查询套件文件的文件系统路径。
指定 scope/name
时,range
和 path
是可选的。 如果省略 range
,则使用指定包的最新版本。 如果省略 path
,则使用指定包的默认查询套件。
path
可以是以下项之一:.ql
查询文件、包含一个或多个查询的目录或 .qls
查询套件文件。 如果省略包名称,则必须提供 path
,它将相对于当前进程的工作目录进行解释。 不支持 glob 模式。
如果同时指定 scope/name
和 path
,则 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
文件中相对于当前工作目录的所有查询。
提示
标准 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 存储库中查看这些查询套件的源。 其他语言的查询套件类似。
运行数据库分析的示例
以下示例演示如何使用 CodeQL 包运行 database analyze
,以及如何使用 CodeQL 存储库的本地签出。 这些示例假定 CodeQL 数据库是在 CodeQL 存储库本地副本的同级目录中创建的。
运行 CodeQL 查询包
注意
CodeQL 包管理功能(包括 CodeQL 包)当前提供 beta 版本,可能会发生更改。 在 beta 版发布期间,CodeQL 包仅可使用 GitHub Packages - GitHub Container registry。 若要使用此 beta 版功能,请安装最新版本的 CodeQL CLI 捆绑包: https://github.com/github/codeql-action/releases 。
若要从 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
时,range
和 path
是可选的。 如果省略 range
,则使用指定包的最新版本。 如果省略 path
,则使用指定包的默认查询套件。
path
可以是 \*.ql
查询文件、包含一个或多个查询的目录或 .qls
查询套件文件。 如果省略包名称,则必须提供 path
,它将相对于当前进程的工作目录进行解释。
如果指定 scope/name
和 path
,则 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-queries
CodeQL 查询包,运行分析,并生成 SARIF 版本 2.1.0 格式的文件,所有版本的 GitHub 都支持该格式的文件。 可通过执行 codeql github upload-results
或代码扫描 API 将此文件上传到 GitHub。
有关详细信息,请参阅“在 CI 系统中配置 CodeQL CLI”或“代码扫描”。
CodeQL 查询套件是 .qls
文件,它们使用指令来选择要根据某些元数据属性运行的查询。 标准 CodeQL 包具有指定代码扫描使用的查询套件位置的元数据,因此 CodeQL CLI 知道在哪里可以自动找到这些套件文件,并且不必在命令行中指定完整路径。
有关详细信息,请参阅“创建 CodeQL 查询套件”。
有关创建自定义查询套件的信息,请参阅“创建 CodeQL 查询套件”。
诊断和摘要信息
创建 CodeQL 数据库时,提取程序会将诊断数据存储在数据库中。 代码扫描查询套件包括用于报告此诊断数据和计算摘要指标的其他查询。 database analyze
命令完成后,CLI 将生成结果文件,并将任何诊断和摘要数据报告到标准输出。 如果选择生成 SARIF 输出,则附加数据也会包含在 SARIF 文件中。
如果分析发现的标准查询结果少于预期,请查看诊断和摘要查询的结果,以检查 CodeQL 数据库是否可能是要分析的代码库的良好表示形式。
将 CodeQL 包集成到 GitHub 中的代码扫描工作流中
可以在代码扫描设置中使用 CodeQL 查询包。 这允许你选择由各种源发布的查询包,并使用其来分析代码。 有关详细信息,请参阅“在 CodeQL 操作中使用 CodeQL 查询包”或“下载和使用 CI 系统中的 CodeQL 查询包”。
在 SARIF 文件中包括自定义 CodeQL 查询的查询帮助
如果使用 CodeQL CLI 在第三方 CI/CD 系统上运行代码扫描分析,则可以在分析期间生成的 SARIF 文件中包括自定义查询的查询帮助。 将 SARIF 文件上传到 GitHub 后,将在代码扫描 UI 中显示查询帮助,以查找自定义查询生成的任何警报。
从 CodeQL CLI v2.7.1 开始,通过在运行 codeql database analyze
时提供 --sarif-add-query-help
选项,可以在 SARIF 文件中包括 markdown 呈现的查询帮助。
有关详细信息,请参阅在 CI 系统中配置 CodeQL CLI。
可以直接在 Markdown 文件中编写自定义查询的查询帮助,并将其与相应的查询一起保存。 或者,为了与标准 CodeQL 查询保持一致,可以采用 .qhelp
格式编写查询帮助。 在 .qhelp
文件中编写的查询帮助不能包含在 SARIF 文件中,并且它们不能通过代码扫描进行处理,因此在运行分析之前必须转换为 markdown。 有关详细信息,请参阅“查询帮助文件”和“测试查询帮助文件”。
结果
可通过多种不同的格式保存分析结果,包括 SARIF 和 CSV。
SARIF 格式旨在表示各种静态分析工具的输出。 有关详细信息,请参阅 SARIF 输出。
如果选择以 CSV 格式生成结果,则输出文件中的每一行都对应一个警报。 每行都是包含以下信息的逗号分隔列表。
属性 | 说明 | 示例 |
---|---|---|
名称 | 标识结果的查询名称。 | Inefficient regular expression |
说明 | 查询的说明。 | A regular expression that requires exponential time to match certain inputs can be a performance bottleneck, and may be vulnerable to denial-of-service attacks. |
severity | 查询的严重性。 | error |
消息 | 警报消息。 | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\\\'. |
路径 | 包含警报的文件的路径。 | /vendor/codemirror/markdown.js |
起始行 | 触发警报的代码开始的文件行。 | 617 |
起始列 | 标记警报代码开头的起始行的列。 如果等于 1,则不包括在内。 | 32 |
结束行 | 触发警报的代码结束的文件行。 当与起始行值相同时,不包括。 | 64 |
结束列 | 如果可用,则为标记警报代码末尾的结束行的列。 否则,将重复结束行。 | 617 |
结果文件可以集成到你自己的代码评审或调试基础结构中。 例如,使用 IDE 的 SARIF 查看器插件,可以使用 SARIF 文件输出在源代码中的正确位置突出显示警报。