Skip to main content

此版本的 GitHub Enterprise Server 已于以下日期停止服务 2023-09-12. 即使针对重大安全问题,也不会发布补丁。 为了获得更好的性能、更高的安全性和新功能,请升级到最新版本的 GitHub Enterprise。 如需升级帮助,请联系 GitHub Enterprise 支持

在 CI 系统中配置 CodeQL CLI

您可以配置持续集成 系统以运行CodeQL CLI,执行 CodeQL 分析,并将结果上传到 GitHub Enterprise Server 以显示为 code scanning 警报。

Code scanning 可用于 GitHub Enterprise Server 中的组织拥有的存储库。 此功能需要 GitHub Advanced Security 的许可证。 有关详细信息,请参阅“关于 GitHub 高级安全性”。

注意:网站管理员必须为 你的 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:

  1. database create 以创建 CodeQL 数据库,用于表示存储库中每种支持的编程语言的层次结构。
  2. 使用 database analyze 运行查询以分析每个 CodeQL 数据库,并将结果汇总到 SARIF 文件中。
  3. github upload-results 将得到的 SARIF 文件上传到结果与分支或拉取请求匹配并显示为 code scanning 警报的 GitHub Enterprise Server。

可以使用 --help 选项显示任何命令的命令行帮助。

注意:上传 SARIF 数据以显示为 GitHub Enterprise Server 中的 code scanning 结果适用于启用了 GitHub Advanced Security 的组织拥有的数据库 。 有关详细信息,请参阅“管理存储库的安全和分析设置”。

创建 CodeQL 数据库进行分析

  1. 查看要分析的代码:

    • 对于分支,请查看要分析的分支的头。
    • 对于拉取请求,请签出拉取请求的头部提交,或签出 GitHub 生成的拉取请求的合并提交。
  2. 设置代码库的环境,确保所有依赖项都可用。 有关详细信息,请参阅“为 CodeQL 分析准备代码”中的“为未编译的语言创建数据库”和“为已编译的语言创建数据库”。

  3. 查找代码库的生成命令(如果有)。 通常可在 CI 系统的配置文件中找到。

  4. 从存储库的签出根目录运行 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指定要为其创建数据库的语言的标识符,请指定以下值之一:cppcsharpgojavajavascriptpython、和 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 命令假定当前目录是源文件的根目录,使用此选项可指定其他位置。
--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-multipythoncpp 子目录中。

$ 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 数据库

  1. 创建 CodeQL 数据库(见上文)。

  2. 对数据库运行 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 文件指定一个语言或其他独特的类别。

延伸阅读