注意:网站管理员必须为 你的 GitHub Enterprise Server 实例 启用 code scanning,然后你才能使用此功能。 有关详细信息,请参阅“为设备配置代码扫描”。
如果企业所有者在企业级别设置了 GitHub Advanced Security (GHAS) 策略,则你可能无法启用或禁用 code scanning。 有关详细信息,请参阅“强制实施企业的代码安全性和分析策略”。
注意:本文介绍了 GitHub Enterprise Server 3.6 的初始发行版中包含的 CodeQL CLI 2.12.7 捆绑包中可用的功能。
如果站点管理员已将 CodeQL CLI 版本更新为较新版本,请参阅本文的 GitHub Enterprise Cloud 版本,了解有关最新功能的信息。
关于使用 CodeQL CLI 生成代码扫描结果
一旦您在 CI 系统中提供了 CodeQL CLI 服务器, 并确保他们可以通过 GitHub Enterprise Server 进行身份验证,便可生成数据。
您使用三个不同的命令生成结果并将它们上传到 GitHub Enterprise Server:
database create
以创建 CodeQL 数据库,用于表示存储库中每种支持的编程语言的层次结构。- 使用
database analyze
运行查询以分析每个 CodeQL 数据库,并将结果汇总到 SARIF 文件中。 github upload-results
将得到的 SARIF 文件上传到结果与分支或拉取请求匹配并显示为 code scanning 警报的 GitHub Enterprise Server。
可以使用 --help
注意:上传 SARIF 数据以显示为 GitHub Enterprise Server 中的 code scanning 结果适用于启用了 GitHub Advanced Security 的组织拥有的数据库 。 有关详细信息,请参阅“管理存储库的安全和分析设置”。
创建 CodeQL 数据库进行分析
-
查看要分析的代码:
- 对于分支,请查看要分析的分支的头。
- 对于拉取请求,请签出拉取请求的头部提交,或签出 GitHub 生成的拉取请求的合并提交。
-
设置代码库的环境,确保所有依赖项都可用。 有关详细信息,请参阅“为 CodeQL 分析准备代码”中的“为未编译的语言创建数据库”和“为已编译的语言创建数据库”。
-
查找代码库的生成命令(如果有)。 通常可在 CI 系统的配置文件中找到。
-
从存储库的签出根目录运行
codeql database create
,并生成代码库。# Single supported language - create one CodeQL database codeql database create <database> --command <build> \ --language=<language-identifier> # Multiple supported languages - create one CodeQL database per language codeql database create <database> --command <build> \ --db-cluster --language=<language-identifier>,<language-identifier>
注意:如果使用容器化构建,需要在执行构建任务的容器内运行 CodeQL CLI。
选项 | 必选 | 使用情况 |
---|---|---|
<database> | 指定要为 CodeQL 数据库创建的目录的名称和位置。 如果尝试覆盖现有目录,则该命令将失败。 如果还指定 --db-cluster ,则这是父目录,并且会为分析的每种语言创建一个子目录。 | |
--language | 指定要为其创建数据库的语言的标识符,请指定以下值之一:cpp 、csharp 、go 、java 、javascript 、python 、和 ruby (使用 javascript 分析 TypeScript 代码 )。 与 --db-cluster | |
--command | (推荐)用于指定为代码库调用生成过程的生成命令或脚本。 命令从当前文件夹运行,或者从定义的位置 --source-root | |
--db-cluster | 在多语言代码库中使用,为 --language | |
--no-run-unnecessary-builds | (推荐)用于抑制 CodeQL CLI 不需要监视生成的语言的生成命令(例如,Python 和 JavaScript/TypeScript)。 | |
--source-root | 如果在存储库的检出根目录之外运行 CLI,请使用此选项。 默认情况下,database create 命令假定当前目录是源文件的根目录,使用此选项可指定其他位置。 | |
--codescanning-config | 高级。 如果具有指定如何创建 CodeQL 数据库以及后续步骤中要运行的查询的配置文件,请进行使用。 有关详细信息,请参阅“自定义 代码扫描的高级设置”和“database create”。 |
有关详细信息,请参阅“为 CodeQL 分析准备代码”。
单语言示例
此示例在 /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)的生成命令。
生成的数据库存储在 /codeql-dbs/example-repo-multi
的 python
和 cpp
子目录中。
$ 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 database analyze
,并指定要使用的查询。codeql database analyze <database> --format=<format> \ --output=<output> <queries>
注意:如果你针对某个提交分析了一个以上的 CodeQL 数据库,需要为此命令生成的每组结果指定 SARIF 类别。 当您上传结果到 GitHub Enterprise Server 时,code scanning 使用此类别来分别存储每种语言的结果。 如果忘记执行此操作,则每次上传都会覆盖之前的结果。
codeql database analyze <database> --format=<format> \
--sarif-category=<language-specifier> --output=<output> \
<queries>
选项 | 必选 | 使用情况 |
---|---|---|
<database> | 指定包含要分析的 CodeQL 数据库的目录路径。 | |
<packs,queries> | 指定要运行 CodeQL 包或查询。 要运行用于 code scanning 的标准查询,请省略此参数。 要查看 CodeQL CLI 捆绑包中包含的其他查询套件,请查看 /<extraction-root>/qlpacks/codeql/<language>-queries/codeql-suites 。 有关创建你自己的查询套件的信息,请参阅 CodeQL CLI 文档中的“创建 CodeQL 查询套件”。 | |
--format | 指定命令生成的结果文件的格式。 要上传到 GitHub,这应该是:sarifv2.1.0 。 有关详细信息,请参阅“对代码扫描的 SARIF 支持”。 | |
--output | 指定保存 SARIF 结果文件的位置。 | |
--sarif-category | 对于单一数据库分析是可选的。 对于在为存储库中的单个提交分析多个数据库时定义语言是必需的。 为此分析指定要包含在 SARIF 结果文件中的类别。 类别用于区分针对同一工具和提交的多个分析,但在不同的语言或代码的不同部分执行。 | |
--sarif-add-query-help | 如果想为分析中使用的自定义查询包含任何可用的 Markdown 呈现查询帮助,请使用此选项。 如果相关查询生成警报,则包含在 SARIF 输出中的自定义查询的任何查询帮助都将显示在代码扫描 UI 中。 有关详细信息,请参阅“使用 CodeQL 查询分析代码”。 | |
--threads | 如果想使用多个线程来运行查询,请使用此选项。 默认值是 1 。 可以指定更多线程来加快查询执行速度。 要将线程数设置为逻辑处理器数,请指定 0 。 | |
--verbose | 用于从数据库创建过程中获取有关分析过程和诊断数据的更多详细信息。 |
有关详细信息,请参阅“使用 CodeQL 查询分析代码”。
分析 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 \
--format=sarifv2.1.0 --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 Enterprise Server
可以检查 SARIF 属性是否具有支持上传的大小,以及该文件是否与代码扫描兼容。 有关详细信息,请参阅“对代码扫描的 SARIF 支持”。
在将结果上传到 GitHub Enterprise Server 之前,必须确定将 GitHub App 或之前创建的 personal access token 传递给 CodeQL CLI 的最佳方式(请参阅在 CI 系统中安装 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-url=<URL> \
--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-url=<URL> \
选项 | 必选 | 使用情况 |
---|---|---|
--repository | 指定要将数据上传到的存储库的所有者/名称。 所有者必须是拥有 GitHub Advanced Security 许可证的企业内的组织,而必须为存储库启用 GitHub Advanced Security。 有关详细信息,请参阅“管理存储库的安全和分析设置”。 | |
--ref | 指定你签出和分析的 ref 的名称,以便使结果与正确的代码匹配。 用于分支:refs/heads/BRANCH-NAME ,用于拉取请求的头提交:refs/pull/NUMBER/head ,或者用于拉取请求的 GitHub 生成的合并提交:refs/pull/NUMBER/merge 。 | |
--commit | 指定分析的提交的完整 SHA。 | |
--sarif | 指定要加载的 SARIF 文件。 | |
--github-url | 指定 GitHub Enterprise Server 的 URL。 | |
--github-auth-stdin | 通过标准输入,将为对 GitHub 的 REST API 进行身份验证而创建的 GitHub App 或 personal access token 从机密存储库传递给 CLI。 如果命令有权访问使用此令牌设置的 GITHUB_TOKEN 环境变量,则不需要执行此操作。 |
有关详细信息,请参阅“github upload-results”。
将结果上传到 GitHub Enterprise Server 的基本示例
下面的示例将结果从 SARIF 文件 temp/example-repo-js.sarif
上传到存储库 my-org/example-repo
。 它告诉 code scanning API,结果用于 main
分支上的提交 deb275d2d5fe9a522a0b7bd8b6b6a1c939552718
。 该示例假设为对 GitHub 的 REST API 进行身份验证而创建的 GitHub App 或 personal access token 使用 GITHUB_TOKEN
环境变量。
codeql github upload-results \
--repository=my-org/example-repo \
--ref=refs/heads/main --commit=deb275d2d5fe9a522a0b7bd8b6b6a1c939552718 \
--sarif=/temp/example-repo-js.sarif --github-url=https://github.example.com \
除非上传未成功,否则此命令不会输出。 上传完成并开始数据处理时,命令提示返回。 在较小的代码库中,您应该能够在稍后的 GitHub Enterprise Server 中探索 code scanning 警告。 可以直接在拉取请求或分支的“安全性”选项卡中查看警报,具体取决于检出的代码。有关详细信息,请参阅“鉴定拉取请求中的代码扫描警报”和“管理存储库的代码扫描警报”。
用于 CodeQL 分析的示例 CI 配置
这是一系列命令的示例,您可以使用两种支持的语言分析代码库,然后上传结果到 GitHub Enterprise Server。
# Create CodeQL databases for Java and Python in the 'codeql-dbs' directory
# Call the normal build script for the codebase: 'myBuildScript'
codeql database create codeql-dbs --source-root=src \
--db-cluster --language=java,python --command=./myBuildScript
# Analyze the CodeQL database for Java, 'codeql-dbs/java'
# Tag the data as 'java' results and store in: 'java-results.sarif'
codeql database analyze codeql-dbs/java java-code-scanning.qls \
--format=sarif-latest --sarif-category=java --output=java-results.sarif
# Analyze the CodeQL database for Python, 'codeql-dbs/python'
# Tag the data as 'python' results and store in: 'python-results.sarif'
codeql database analyze codeql-dbs/python python-code-scanning.qls \
--format=sarif-latest --sarif-category=python --output=python-results.sarif
# Upload the SARIF file with the Java results: 'java-results.sarif'
# The GitHub App or personal access token created for authentication
# with GitHub's REST API is available in the `GITHUB_TOKEN` environment variable.
codeql github upload-results \
--repository=my-org/example-repo \
--ref=refs/heads/main --commit=deb275d2d5fe9a522a0b7bd8b6b6a1c939552718 \
--sarif=java-results.sarif
# Upload the SARIF file with the Python results: 'python-results.sarif'
codeql github upload-results \
--repository=my-org/example-repo \
--ref=refs/heads/main --commit=deb275d2d5fe9a522a0b7bd8b6b6a1c939552718 \
--sarif=python-results.sarif
CI 系统中的 CodeQL CLI 疑难解答
查看日志和诊断信息
当您使用 code scanning 查询套件分析 CodeQL 数据库时,除了生成有关警报的详细信息外,CLI 还报告数据库生成步骤和汇总指标的诊断数据。 对于警报很少的存储库,您可能会发现此信息可用于确定代码中是否真的存在很少的问题,或者生成 CodeQL 数据库时是否出错。 要获取 codeql database analyze
更详细的输出,请使用 --verbose
选项。
有关可用诊断信息类型的详细信息,请参阅“查看代码扫描日志”。
Code scanning 只显示被分析语言之一的分析结果
默认情况下, code scanning 预计每个仓库需要一个SARIF 结果文件。 因此,当您上传第二个 SARIF 结果文件进行提交时,将被视为原始数据集的替换。
如果您想将多组结果上传到 code scanning API 以在存储库中提交,则必须将每组结果识别为唯一的一组结果。 对于需要创建多个 CodeQL 数据库来分析每个提交的存储库,使用 --sarif-category
为每个为该存储库生成的 SARIF 文件指定一个语言或其他独特的类别。