使用 CodeQL CLI
除了 GitHub.com 上的图形用户界面,还可通过命令行接口访问许多相同的主要 CodeQL 功能。
本单元将介绍使用 CodeQL CLI 创建数据库、分析数据库并将结果上传到 GitHub。
CodeQL CLI 命令
将 CodeQL CLI 提供给 CI 系统中的服务器,并确保它们可以使用 GitHub 进行身份验证后,即可生成数据。
可使用三个不同的命令生成结果并将结果上传到 GitHub:
database create
用于创建 CodeQL 数据库,以表示存储库中每种受支持的编程语言的层次结构。database analyze
用于运行查询,以分析每个 CodeQL 数据库并将结果汇总到 SARIF 文件中。github upload-results
用于将生成的 SARIF 文件上传到 GitHub,其中结果与分支或拉取请求匹配并显示为代码扫描警报。
可以使用 --help option
显示任何命令的命令行帮助。
对于启用了 GitHub 高级安全的组织拥有的存储库以及 GitHub.com 上的公共存储库,支持上传 SARIF 数据以在 GitHub 中显示为代码扫描结果。
创建 CodeQL 数据库进行分析
按照以下步骤创建 CodeQL 数据库进行分析。
- 查看要分析的代码:
- 对于分支,请查看要分析的分支的头。
- 对于拉取请求,请查看拉取请求的头提交,或查看拉取请求的 GitHub 生成的合并提交。
- 设置代码库的环境,确保所有依赖项都可用。
- 查找代码库的生成命令(如果有)。 通常可在 CI 系统的配置文件中找到。
- 从存储库的签出根目录运行
codeql database create
,并生成代码库:若要为一种受支持的语言创建一个 CodeQL 数据库,请使用以下命令:
codeql database create <database> --command <build> --language=<language-identifier>
若要为多种受支持的语言分别创建一个 CodeQL 数据库,请使用以下命令:
codeql database create <database> --command <build> \ --db-cluster --language=<language-identifier>,<language-identifier>
注意
如果使用容器化生成,则需要在执行生成任务的容器内运行 CodeQL CLI。
下表显示了 database create
命令的完整参数列表:
选项 | 所需用法 |
---|---|
<database> |
指定要为 CodeQL 数据库创建的目录的名称和位置。 如果尝试覆盖现有目录,则该命令将失败。 如果还指定 --db-cluster ,则这是父目录,并且会为分析的每种语言创建一个子目录。 |
--language |
指定语言的标识符,以便为其中一个cpp go csharp 、、java javascript 、、和 python ruby (使用 JavaScript 分析 TypeScript 代码)创建数据库。 与 --db-cluster 一起使用时,该选项接受逗号分隔的列表,也可以多次指定。 |
--command |
推荐。 用于指定为代码库调用生成过程的生成命令或脚本。 命令从当前文件夹运行,或从定义的--source-root 目录运行。 Python 和 JavaScript/TypeScript 分析不需要。 |
--db-cluster |
可选。 在多语言代码库中使用,为 --language 指定的每种语言生成一个数据库。 |
--no-run-unnecessary-builds |
推荐。 用于抑制生成命令,以便在 CodeQL CLI 不需要监控生成过程的语言(例如 Python 和 JavaScript/TypeScript)中使用。 |
--source-root |
可选。 如果在存储库的检出根目录之外运行 CLI,请使用此选项。 默认情况下,database create 命令假定当前目录是源文件的根目录,使用此选项可指定其他位置。 |
单语言示例
此示例为在 /checkouts/example-repo
签出的存储库创建一个 CodeQL 数据库。 它使用 JavaScript 提取器在存储库中创建 JavaScript 和 TypeScript 代码的分层表示形式。 生成的数据库存储在 /codeql-dbs/example-repo
中。
$ codeql database create /codeql-dbs/example-repo --language=javascript \
--source-root /checkouts/example-repo
> Initializing database at /codeql-dbs/example-repo.
> Running command [/codeql-home/codeql/javascript/tools/autobuild.cmd]
in /checkouts/example-repo.
> [build-stdout] Single-threaded extraction.
> [build-stdout] Extracting
...
> Finalizing database at /codeql-dbs/example-repo.
> Successfully created database at /codeql-dbs/example-repo.
多语言示例
此示例为在 /checkouts/example-repo-multi
签出的存储库创建两个 CodeQL 数据库。 它使用:
--db-cluster
用于请求分析多种语言。--language
用于指定要为其创建数据库的语言。--command
用于告知工具代码库的生成命令,此处为 make。--no-run-unnecessary-builds
指示工具跳过不需要的语言的生成命令(如 Python)。
生成的数据库存储在 python
的 cpp
和 /codeql-dbs/example-repo-multi
子目录中。
$ codeql database create /codeql-dbs/example-repo-multi \
--db-cluster --language python,cpp \
--command make --no-run-unnecessary-builds \
--source-root /checkouts/example-repo-multi
Initializing databases at /codeql-dbs/example-repo-multi.
Running build command: [make]
[build-stdout] Calling python3 /codeql-bundle/codeql/python/tools/get_venv_lib.py
[build-stdout] Calling python3 -S /codeql-bundle/codeql/python/tools/python_tracer.py -v -z all -c /codeql-dbs/example-repo-multi/python/working/trap_cache -p ERROR: 'pip' not installed.
[build-stdout] /usr/local/lib/python3.6/dist-packages -R /checkouts/example-repo-multi
[build-stdout] [INFO] Python version 3.6.9
[build-stdout] [INFO] Python extractor version 5.16
[build-stdout] [INFO] [2] Extracted file /checkouts/example-repo-multi/hello.py in 5ms
[build-stdout] [INFO] Processed 1 modules in 0.15s
[build-stdout] <output from calling 'make' to build the C/C++ code>
Finalizing databases at /codeql-dbs/example-repo-multi.
Successfully created databases at /codeql-dbs/example-repo-multi.
$
分析 CodeQL 数据库
创建 CodeQL 数据库后,请按照以下步骤进行分析:
- 可选择运行
codeql pack download <packs>
以下载要在分析期间运行的任何 CodeQL 包(beta 版本)。 codeql database analyze
在数据库上运行,并指定要使用的包和/或查询。
codeql database analyze <database> --format=<format> \
--output=<output> <packs,queries>
注意
如果为单个提交分析多个 CodeQL 数据库,则必须为该命令生成的每组结果指定一个 SARIF 类别。 将结果上传到 GitHub 时,代码扫描将使用此类别分别存储每种语言的结果。 如果忘记执行此操作,则每次上传都会覆盖之前的结果。
codeql database analyze <database> --format=<format> \
--sarif-category=<language-specifier> --output=<output> \
<packs,queries>
下表显示了 database analyze
命令的完整参数列表:
选项 | 所需用法 |
---|---|
<database> |
指定包含要分析的 CodeQL 数据库的目录的路径。 |
<packs,queries> |
指定要运行的 CodeQL 包或查询。 若要运行用于代码扫描的标准查询,请省略此参数。 若要查看 CodeQL CLI 捆绑包中包含的其他查询套件,请参阅 /<extraction-root>/codeql/qlpacks/codeql-<language>/codeql-suites 。 有关创建自己的查询套件的信息,请参阅 CodeQL CLI 文档中的“创建 CodeQL 查询套件”[5]。 |
--format |
指定命令生成的结果文件的格式。 若要上传到 GitHub,则应该是:sarif-latest 。 |
--output |
指定保存 SARIF 结果文件的位置。 |
--sarif-category |
对于单一数据库分析是可选的。 对于在为存储库中的单个提交分析多个数据库时定义语言是必需的。 为此分析指定要包含在 SARIF 结果文件中的类别。 类别用于区分针对同一工具和提交的多个分析,但在不同的语言或代码的不同部分执行。 |
--sarif-add-query-help |
可选。 如果想为分析中使用的自定义查询包含任何可用的 Markdown 呈现查询帮助,请使用此选项。 如果相关查询生成警报,则包含在 SARIF 输出中的自定义查询的任何查询帮助都将显示在代码扫描 UI 中。 |
<packs> |
可选。 如果已下载 CodeQL 查询包,并希望运行包中指定的默认查询或查询套件,请使用此选项。 |
--threads |
可选。 如果想使用多个线程来运行查询,请使用此选项。 默认值为 1。 可以指定更多线程来加快查询执行速度。 若要将线程数设置为逻辑处理器数,请指定 0。 |
--verbose |
可选。 用于从数据库创建过程中获取有关分析过程和诊断数据的更多详细信息。 |
基本示例
此示例分析存储在 /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
--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
SARIF 上传最多支持每次上传 25,000 个结果。 但是,仅显示前 5,000 个结果,按严重性确定优先级。 如果工具生成太多结果,则应更新配置,以将重点放在最重要的规则或查询的结果上。
对于每次上传,SARIF 上传支持最大大小为 10 MB 的 gzip 压缩 SARIF 文件。 任何超过此限制的上传都将被拒绝。 如果 SARIF 文件由于包含太多结果而过大,则应更新配置,以将重点放在最重要的规则或查询的结果上。 有关限制和验证 SARIF 文件的详细信息,请参阅文档[6]。
在将结果上传到 GitHub 之前,必须确定将之前创建的 GitHub 应用或个人访问令牌传递给 CodeQL CLI 的最佳方式。 建议查看 CI 系统有关安全使用机密存储的指南。 CodeQL CLI 支持:
- 使用 --github-auth-stdin 选项与机密存储库进行交互。 这是推荐的身份验证方法。
- 将机密保存在环境变量
GITHUB_TOKEN
中,并在不包含--github-auth-stdin
选项的情况下运行 CLI。 - 传递 --github-auth-stdin 命令行选项,并通过标准输入提供临时令牌。 建议将此用于测试目的。
为 CI 服务器确定最安全可靠的方法后,请在每个 SARIF 结果文件上运行 codeql github upload-results
并包含 --github-auth-stdin
,除非该令牌在环境变量 GITHUB_TOKEN
中可用。
# GitHub App or personal access token available from a secret store
<call-to-retrieve-secret> | codeql github upload-results \
--repository=<repository-name> \
--ref=<ref> --commit=<commit> \
--sarif=<file> --github-auth-stdin
# GitHub App or personal access token available in GITHUB_TOKEN
codeql github upload-results \
--repository=<repository-name> \
--ref=<ref> --commit=<commit> \
--sarif=<file>
命令的完整参数 github upload-results
列表显示在表中,如下所示。
选项 | 所需用法 |
---|---|
--repository |
指定要将数据上传到的存储库的所有者/名称。 所有者必须是企业内拥有 GitHub 高级安全许可证的组织,并且必须为存储库启用 GitHub 高级安全,除非存储库是公共的。 |
--ref |
指定你签出和分析的引用的名称,以便使结果与正确的代码匹配。 对于分支,使用 refs/heads/BRANCH-NAME ;对于拉取请求的 head 提交,使用 refs/pulls/NUMBER/head ;对于 GitHub 生成的拉取请求合并提交,使用 refs/pulls/NUMBER/merge 。 |
--commit |
指定分析的提交的完整 SHA。 |
--sarif |
指定要加载的 SARIF 文件。 |
--github-auth-stdin |
可选。 用于通过标准输入向 CLI 传递 GitHub 应用或为使用 GitHub 的 REST API 进行身份验证而创建的个人访问令牌。 如果命令有权访问使用此令牌设置的 GITHUB_TOKEN 环境变量,则不需要执行此操作。 |