Skip to main content
我们经常发布文档更新,此页面的翻译可能仍在进行中。 有关最新信息,请访问英语文档

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

创建 CodeQL 数据库

可以生成 CodeQL 数据库,其中包含查询代码所需的数据。

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

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

注意:本文已于 2023 年 1 月从 CodeQL 文档网站迁移。

关于创建 CodeQL 数据库

注意:本文介绍了 GitHub Enterprise Server 3.4 的初始发行版中包含的 CodeQL CLI 2.7.6 捆绑包中可用的功能。

如果站点管理员已将 CodeQL CLI 版本更新为较新版本,请参阅本文的 GitHub Enterprise Cloud 版本,了解有关最新功能的信息。

在使用 CodeQL 分析代码之前,需要创建一个 CodeQL 数据库,其中包含对代码运行查询所需的所有数据。 可以使用 CodeQL CLI 自行创建 CodeQL 数据库,也可以从 GitHub.com 下载这些数据库。

CodeQL 分析依赖于从代码中提取关系数据,并使用它来生成 CodeQL 数据库。 CodeQL 数据库包含有关代码库的所有重要信息,可通过执行 CodeQL 查询对其进行分析。 GitHub 为大量开源项目创建和存储 CodeQL 数据库。 有关详细信息,请参阅“从 GitHub.com 下载 CodeQL 数据库”。

还可以使用 CodeQL CLI 自行创建 CodeQL 数据库。 在生成 CodeQL 数据库之前,需要:

  • 安装并设置 CodeQL CLI。 有关详细信息,请参阅“CodeQL CLI 入门指南”。
  • 查看要分析的代码库版本。 目录应已准备好生成,并且所有依赖项均已安装。

有关在第三方 CI 系统中使用 CodeQL CLI 创建在 GitHub 中显示为代码扫描警报的结果的信息,请参阅 在 CI 系统中配置 CodeQL CLI。 有关使用 GitHub Actions 启用 CodeQL 代码扫描的信息,请参阅为存储库设置代码扫描

正在运行 codeql database create

CodeQL 数据库是通过从项目的签出根目录运行以下命令创建的:

codeql database create <database> --language=<language-identifier>

必须指定以下内容:

  • <database>:要创建的新数据库的路径。 执行命令时将创建此目录,无法指定现有目录。
  • --language:要为其创建数据库的语言的标识符。 与 --db-cluster 一起使用时,该选项接受逗号分隔的列表,也可以多次指定。 CodeQL 支持为以下语言创建数据库:
语言标识符
C/C++cpp
C#csharp
Gogo
Javajava
JavaScript/TypeScriptjavascript
Pythonpython
Rubyruby

注意:用于 Ruby 的 CodeQL 分析目前为 beta 版。 在 beta 版中,Ruby 的分析将不如其他语言的 CodeQL 分析全面。

如果需要编译代码,以及如果要为多种语言创建 CodeQL 数据库,可以根据源文件的位置指定其他选项:

  • --source-root:创建数据库时使用的主要源文件的根文件夹。 默认情况下,命令假定当前目录是源根目录,使用此选项可指定其他位置。
  • --db-cluster:用于多语言代码库(如果要为多语言创建数据库)。
  • --command:在为一个或多个已编译语言创建数据库时使用,如果请求的唯一语言是 Python 和 JavaScript,则省略。 这指定调用编译器所需的生成命令。 从当前文件夹运行命令,如果指定,则从 --source-root 运行。 如果未包含 --command,CodeQL 将尝试使用内置的自动生成程序自动检测生成系统。
  • --no-run-unnecessary-builds:与 --db-cluster 一起使用,以抑制 CodeQL CLI 不需要监视生成的语言的生成命令(例如,Python 和 JavaScript/TypeScript)。

可以指定提取程序选项来自定义创建 CodeQL 数据库的提取程序的行为。 有关详细信息,请参阅“提取程序选项”。

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

进度和结果

如果指定的选项存在任何问题,将报告错误。 对于解释的语言,提取进度显示在控制台中,对于每个源文件,它会报告提取是否成功或失败。 对于已编译的语言,控制台将显示生成系统的输出。

成功创建数据库后,会在命令中指定的路径处找到一个新目录。 如果使用 --db-cluster 选项创建多个数据库,则会为每种语言创建一个子目录。 每个 CodeQL 数据库目录包含许多子目录,包括关系数据(分析所需)以及用于显示分析结果的源存档(创建数据库时制作的源文件的副本)。

为非编译语言创建数据库

CodeQL CLI 包括为非编译语言(特别是 JavaScript(和 TypeScript)、Python 和 Ruby)创建数据库的提取程序。 如果在执行 database create 时将 JavaScript、Python 或 Ruby 指定为 --language 选项,则会自动调用这些提取程序。 为这些语言创建数据库时,必须确保所有其他依赖项都可用。

注意:为 JavaScript、TypeScript、Python 和 Ruby 运行 database create 时,不应指定 --command 选项。 否则,此操作将替代正常的提取程序调用,将创建一个空数据库。 如果为多种语言创建数据库,并且其中一种语言为已编译语言,请使用 --no-run-unnecessary-builds 选项跳过不需要编译的语言的命令。

JavaScript 和 TypeScript

为 JavaScript 创建数据库不需要其他依赖项,但如果项目包含 TypeScript 文件,则必须安装 Node.js 6.x 或更高版本。 在命令行中,可以指定 --language=javascript 提取 JavaScript 和 TypeScript 文件:

codeql database create --language=javascript --source-root <folder-to-extract> <output-folder>/javascript-database

此处,我们指定了一个 --source-root 路径,该路径是执行数据库创建的位置,但不一定是代码库的签出根。

默认情况下,不会提取 node_modulesbower_components 目录中的文件。

Python

创建适用于 Python 的数据库时,必须确保:

  • 已安装 Python 3,可用于 CodeQL 提取程序。
  • 已安装代码使用的 Python 版本。
  • 你有权访问 pip 打包管理系统,并且可以安装代码库所依赖的任何包。
  • 已安装 virtualenv pip 模块。

在命令行中,必须指定 --language=python。 例如:

codeql database create --language=python <output-folder>/python-database

这会从代码的签出根执行 database create 子命令,在 <output-folder>/python-database 生成新的 Python 数据库。

Ruby

为 Ruby 创建数据库不需要额外的依赖项。 在命令行中,必须指定 --language=ruby。 例如:

codeql database create --language=ruby --source-root <folder-to-extract> <output-folder>/ruby-database

此处,我们指定了一个 --source-root 路径,该路径是执行数据库创建的位置,但不一定是代码库的签出根。

为已编译语言创建数据库

对于已编译语言,CodeQL 需要调用所需的生成系统来生成数据库,因此生成方法必须可用于 CLI。

检测生成系统

注意:用于 Kotlin 的 CodeQL 分析目前为 beta 版。 在 Beta 版中,Kotlin 代码的分析以及随附文档不会像其他语言那样全面。

CodeQL CLI 包括适用于 C/C++、C#、Go 和 Java 代码的自动生成程序。 CodeQL 自动生成程序允许为编译语言生成项目,而无需指定任何生成命令。 调用自动生成程序时,CodeQL 检查源以获取生成系统的证据,并尝试运行提取数据库所需的最佳命令集。

如果不包含 --command 选项,则为已编译的 --language 执行 codeql database create 时自动调用自动生成程序。 例如,对于 Java 代码库,只需运行:

codeql database create --language=java <output-folder>/java-database

如果代码库使用标准生成系统,则依赖于自动生成程序通常是创建数据库的最简单方法。 对于需要非标准生成步骤的源,可能需要在命令行中显式定义每个步骤。

注意:

  • 如果要生成 Go 数据库,请安装 Go 工具链(版本 1.11 或更高版本),如果有依赖项,则相应的依赖项管理器(如 dep)。

  • Go 自动生成程序尝试自动检测在存储库中用 Go 编写的代码,并且仅在尝试提取依赖项时运行生成脚本。 若要强制 CodeQL 将提取限制为由生成脚本编译的文件,请设置环境变量 CODEQL_EXTRACTOR_GO_BUILD_TRACING=on 或使用 --command 选项指定生成命令。

指定生成命令

以下示例旨在让你了解可为编译语言指定的一些生成命令。

注意:--command 选项接受单个参数,如果需要使用多个命令,请多次指定 --command。 如果需要传递子命令和选项,则需要引用整个参数才能正确解释。

  • 使用 make 生成的 C/C++ 项目:

    codeql database create cpp-database --language=cpp --command=make
    
  • 使用 dotnet build 生成的 C# 项目:

    最好添加 /t:rebuild 以确保生成所有代码,或者先执行 dotnet clean(未生成的代码不会包含在 CodeQL 数据库中):

    codeql database create csharp-database --language=csharp --command='dotnet build /t:rebuild'
    
  • 使用 CODEQL_EXTRACTOR_GO_BUILD_TRACING=on 环境变量生成的 Go 项目:

    CODEQL_EXTRACTOR_GO_BUILD_TRACING=on codeql database create go-database --language=go
    
  • 使用自定义生成脚本生成的 Go 项目:

    codeql database create go-database --language=go --command='./scripts/build.sh'
    
  • 使用 Gradle 生成的 Java 项目:

    # Use `--no-daemon` because a build delegated to an existing daemon cannot be detected by CodeQL:
    codeql database create java-database --language=java --command='gradle --no-daemon clean test'
    
  • 使用 Maven 生成的 Java 项目:

    codeql database create java-database --language=java --command='mvn clean install'
    
  • 使用 Ant 生成的 Java 项目:

    codeql database create java-database --language=java --command='ant -f build.xml'
    
  • 使用 Bazel 生成的项目:

    # Navigate to the Bazel workspace.
    
    # Before building, remove cached objects
    # and stop all running Bazel server processes.
    bazel clean --expunge
    
    # Build using the following Bazel flags, to help CodeQL detect the build:
    # `--spawn_strategy=local`: build locally, instead of using a distributed build
    # `--nouse_action_cache`: turn off build caching, which might prevent recompilation of source code
    # `--noremote_accept_cached`, `--noremote_upload_local_results`: avoid using a remote cache
    codeql database create new-database --language=<language> \
    --command='bazel build --spawn_strategy=local --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results //path/to/package:target'
    
    # After building, stop all running Bazel server processes.
    # This ensures future build commands start in a clean Bazel server process
    # without CodeQL attached.
    bazel shutdown
    
  • 使用自定义生成脚本生成的项目:

    codeql database create new-database --language=<language> --command='./scripts/build.sh'
    

此命令运行包含生成项目所需的所有命令的自定义脚本。

使用间接生成跟踪

如果编译语言的 CodeQL CLI 自动生成程序不适用于 CI 工作流,并且无法使用 codeql database trace-command 包装生成命令的调用,可以使用间接生成跟踪来创建 CodeQL 数据库。 若要使用间接生成跟踪,CI 系统必须能够为每个生成操作设置自定义环境变量。

若要使用间接生成跟踪创建 CodeQL 数据库,请从项目的签出根目录运行以下命令:

codeql database init ... --begin-tracing <database>

必须指定以下内容:

  • <database>:要创建的新数据库的路径。 执行命令时将创建此目录,无法指定现有目录。
  • --begin-tracing:创建可用于设置环境的脚本,将在该环境中跟踪生成命令。

可以像平常一样为 codeql database init 命令指定其他选项。

注意:如果生成在 Windows 上运行,则必须设置 --trace-process-level <number>--trace-process-name <parent process name>,以便该选项指向父 CI 进程,该进程将观察所分析代码的所有生成步骤。

codeql database init 命令将输出消息:

Created skeleton <database>. This in-progress database is ready to be populated by an extractor. In order to initialise tracing, some environment variables need to be set in the shell your build will run in. A number of scripts to do this have been created in <database>/temp/tracingEnvironment. Please run one of these scripts before invoking your build command.

Based on your operating system, we recommend you run: ...

codeql database init 命令使用包含环境变量和值的文件创建 <database>/temp/tracingEnvironment,这些环境变量和值将启用 CodeQL 跟踪一系列生成步骤。 这些文件名为 start-tracing.{json,sh,bat,ps1}。 将其中一个文件与 CI 系统的机制结合使用,以便为将来的步骤设置环境变量。 方法:

  • 读取 JSON 文件,对其进行处理,然后以 CI 系统所需的格式输出环境变量。 例如,Azure DevOps 需要 echo "##vso[task.setvariable variable=NAME]VALUE"
  • 或者,如果 CI 系统保留该环境,请获取适当的 start-tracing 脚本以在 CI 系统的 shell 环境中设置 CodeQL 变量。

生成代码;(可选)使用存储 start-tracing 脚本的目录中的 end-tracing.{json,sh,bat,ps1} 脚本取消设置环境变量;然后运行命令 codeql database finalize <database>

使用间接生成跟踪创建 CodeQL 数据库后,可以像使用任何其他 CodeQL 数据库一样使用该数据库。 例如,如果使用的是代码扫描,请分析数据库并将结果上传到 GitHub。

使用间接生成跟踪创建 CodeQL 数据库的示例

注意:如果使用 Azure DevOps 管道,则创建 CodeQL 数据库最简单的方法是使用 GitHub Advanced Security for Azure DevOps。 有关文档,请参阅 Microsoft Learn 中的配置 GitHub Advanced Security for Azure DevOps

以下示例演示如何在 Azure DevOps 管道中使用间接生成跟踪来创建 CodeQL 数据库:

steps:
    # Download the CodeQL CLI and query packs...
    # Check out the repository ...

    # Run any pre-build tasks, for example, restore NuGet dependencies...

    # Initialize the CodeQL database.
    # In this example, the CodeQL CLI has been downloaded and placed on the PATH.
    - task: CmdLine@1
       displayName: Initialize CodeQL database
      inputs:
          # Assumes the source code is checked out to the current working directory.
          # Creates a database at `<current working directory>/db`.
          # Running on Windows, so specifies a trace process level.
          script: "codeql database init --language csharp --trace-process-name Agent.Worker.exe --source-root . --begin-tracing db"

    # Read the generated environment variables and values,
    # and set them so they are available for subsequent commands
    # in the build pipeline. This is done in PowerShell in this example.
    - task: PowerShell@1
       displayName: Set CodeQL environment variables
       inputs:
          targetType: inline
          script: >
             $json = Get-Content $(System.DefaultWorkingDirectory)/db/temp/tracingEnvironment/start-tracing.json | ConvertFrom-Json
             $json.PSObject.Properties | ForEach-Object {
                 $template = "##vso[task.setvariable variable="
                 $template += $_.Name
                 $template += "]"
                 $template += $_.Value
                 echo "$template"
             }

    # Execute the pre-defined build step. Note the `msbuildArgs` variable.
    - task: VSBuild@1
        inputs:
          solution: '**/*.sln'
          msbuildArgs: /p:OutDir=$(Build.ArtifactStagingDirectory)
          platform: Any CPU
          configuration: Release
          # Execute a clean build, in order to remove any existing build artifacts prior to the build.
          clean: True
       displayName: Visual Studio Build

    # Read and set the generated environment variables to end build tracing. This is done in PowerShell in this example.
    - task: PowerShell@1
       displayName: Clear CodeQL environment variables
       inputs:
          targetType: inline
          script: >
             $json = Get-Content $(System.DefaultWorkingDirectory)/db/temp/tracingEnvironment/end-tracing.json | ConvertFrom-Json
             $json.PSObject.Properties | ForEach-Object {
                 $template = "##vso[task.setvariable variable="
                 $template += $_.Name
                 $template += "]"
                 $template += $_.Value
                 echo "$template"
             }

    - task: CmdLine@2
       displayName: Finalize CodeQL database
       inputs:
          script: 'codeql database finalize db'

    # Other tasks go here, for example:
    # `codeql database analyze`
    # then `codeql github upload-results` ...

从 GitHub.com 下载数据库

GitHub 在 GitHub.com 上存储超过 200,000 个存储库的 CodeQL 数据库,可以使用 REST API 下载这些存储库。 存储库列表在不断发展壮大,以确保其包含最有趣的安全研究代码库。

可以使用 /repos/<owner>/<repo>/code-scanning/codeql/databases 终结点检查存储库是否有任何 CodeQL 数据库可供下载。 例如,若要使用 GitHub CLI 检查 CodeQL 数据库,需要运行:

gh api /repos/<owner>/<repo>/code-scanning/codeql/databases/

此命令返回有关可用于存储库的任何 CodeQL 数据库的信息,包括数据库表示的语言以及数据库上次更新的时间。 如果没有 CodeQL 数据库可用,则响应为空。

确认存在感兴趣的语言的 CodeQL 数据库后,可以使用以下命令下载该数据库:

gh api /repos/<owner>/<repo>/code-scanning/codeql/databases/<language> -H 'Accept: application/zip' > path/to/local/database.zip

有关详细信息,请参阅获取 CodeQL 数据库终结点文档。

在使用 CodeQL CLI 运行分析之前,必须解压缩数据库。

延伸阅读