为 CodeQL 准备数据库

已完成

CodeQL 将代码视为数据。 使用从代码库提取的可查询数据创建数据库。 然后,可以对此数据库运行 CodeQL 查询,以识别安全漏洞、bug 和其他错误。 可以编写自己的查询或运行 GitHub 研究人员和社区参与者编写的标准 CodeQL 查询。

在本单元中,你将了解如何创建数据库。 在分析代码之前,需要执行此步骤。 需要创建一个 CodeQL 数据库,该数据库包含对代码运行查询所需的所有数据。

CodeQL 分析依赖于从代码中提取关系数据,并使用它生成 CodeQL 数据库。 这些数据库包含有关代码库的所有重要信息。

可以使用 CodeQL CLI 独立产品来分析代码并生成代码库的数据库表示形式。 数据库准备就绪后,可以查询数据库或运行一组查询,以在静态分析结果交换格式(SARIF)中生成一组结果。

为 CodeQL 准备数据库

在生成 CodeQL 数据库之前,需要安装和设置 CodeQL CLI。 然后,需要查看要分析的代码库版本。

对于编译型语言,目录应准备好构建,并且已安装所有依赖项。 CodeQL 首先提取代码库中每个源文件的单个关系表示形式来创建数据库。 使用此数据库分析代码。

对于解释的语言,提取程序直接在源代码上运行。 此功能提供代码库的准确表示形式并解析任何依赖项。

从代码库提取源文件的工作原理是监视已编译语言的正常生成过程。 每次调用编译器来处理源文件时,CodeQL 都会创建源文件的副本。 它与每个源文件一起收集有关源代码的所有相关信息。

CLI 设置

使用以下步骤设置 CodeQL CLI。

1. 下载 CodeQL CLI 文件夹中的 .zip 包

建议通过下载捆绑包来安装 CodeQL CLI 和查询。 此方法有助于确保兼容性并提高性能,而不是单独下载 CLI 和查询。

CodeQL CLI 下载包是一个 .zip 存档,其中包含工具、脚本和各种特定于 CodeQL 的文件。 捆绑包包括:CodeQL CLI、CodeQL GitHub 存储库中的查询和库的兼容版本,以及包含的查询的预编译版本。

  1. 转到 CodeQL 公共存储库的“发布”页
  2. “资产”下下载特定于平台的捆绑包。

“发布 ”页上,还可以查看版本的更改日志以及以前版本的 CodeQL 捆绑包的下载。 如有必要,可以下载 codeql-bundle.tar.gz,其中包含所有受支持平台的 CLI。

2.提取 .zip 存档

如果使用 Linux、Windows 或 macOS,则可以将 .zip 存档提取到所选目录中。

macOS Catalina(或更高版本)的用户需要采取进一步措施。 有关详细信息,请参阅 有关 CLI 入门的 CodeQL 文档

3. 运行 CodeQL 进程

提取后,请执行以下步骤之一,以使用 codeql 可执行文件运行 CodeQL 进程:

  • 运行 <extraction-root>/codeql/codeql,其中 <extraction-root> 是解压 CodeQL CLI 包的文件夹。
  • <extraction-root>/codeql添加到PATH条目中,以便可以直接运行可执行文件codeql

现在,可以运行 CodeQL 命令。

验证你的 CLI 设置

可以运行 CodeQL CLI 子命令来验证是否正确设置了 CLI 并可以分析数据库:

  • 运行 codeql resolve packs(如果您已将 codeql 添加到 PATH)以显示 CLI 可以找到哪些 CodeQL 包。 否则使用 /<extraction-root>/codeql/codeql resolve packs。 此命令显示 CodeQL CLI 捆绑包中包含的 CodeQL 包的名称,如前面的步骤 <extraction-root>所示。

    如果 CodeQL CLI 找不到所需语言的 CodeQL 包,请检查是否已下载 CodeQL 捆绑包,而不是 CodeQL CLI 的独立副本。

  • 运行 codeql resolve languages 以显示 CodeQL CLI 包默认支持的语言。

数据库创建

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

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

在命令中:

  • <database> 替换为要创建的新数据库的路径。
  • <language-identifier> 替换为用于创建数据库的语言标识符。 可以使用此标识符 --db-cluster 来接受逗号分隔的列表,也可以多次指定它。

还可以指定以下选项。 这些选项取决于源文件的位置、是否需要编译代码,还是要为多种语言创建 CodeQL 数据库。

  • 用于 --source-root 标识用于创建数据库的主要源文件的根文件夹。
  • 在多语言代码库中使用 --db-cluster 以创建多个语言的数据库。
  • 为一个或多个已编译语言创建数据库时使用 --command 。 如果仅使用 Python 和 JavaScript,则不需要此选项。
  • --no-run-unnecessary-builds--db-cluster 一起使用,以禁用 CodeQL CLI 不需要监视生成的语言的生成命令。

成功创建数据库后,命令中指定的路径上会显示一个新目录。 如果使用 --db-cluster 选项创建了多个数据库,会为每种语言创建一个子目录。

每个 CodeQL 数据库目录都包含多个子目录,包括用于分析和源存档的关系数据。 源存档是创建数据库时创建的源文件的副本。 CodeQL 使用它来显示分析结果。

提取装置

提取程序是为每个输入文件生成关系数据和源引用的工具,可以从中构建 CodeQL 数据库。 CodeQL 支持的每种语言都有一个提取程序。 此结构可确保提取过程尽可能准确。

每个提取程序都定义了自己的一组配置选项。 输入 codeql resolve extractor --format=betterjson 会导致数据格式化为如下示例:

{
    "extractor_root" : "/home/user/codeql/java",
    "extractor_options" : {
        "option1" : {
            "title" : "Java extractor option 1",
            "description" : "An example string option for the Java extractor.",
            "type" : "string",
            "pattern" : "[a-z]+"
        },
        "group1" : {
            "title" : "Java extractor group 1",
            "description" : "An example option group for the Java extractor.",
            "type" : "object",
            "properties" : {
                "option2" : {
                    "title" : "Java extractor option 2",
                    "description" : "An example array option for the Java extractor",
                    "type" : "array",
                    "pattern" : "[1-9][0-9]*"
                }
            }
        }
    }
}

若要了解哪些选项可用于语言的提取程序,请输入 codeql resolve languages --format=betterjsoncodeql resolve extractor --format=betterjsonbetterjson 输出格式还提供提取程序的根和其他特定于语言的选项。

CodeQL 数据库中的数据

CodeQL 数据库是一个目录,其中包含分析所需的所有数据。 此数据包括关系数据、复制的源文件以及针对特定语言的数据库架构,该架构指定了数据中的相互关系。 CodeQL 在提取后导入此数据。

CodeQL 数据库提供从代码库中提取的特定语言可查询数据的快照。 此数据是代码的完整分层表示形式。 它包括抽象语法树、数据流图和控制流图的表示形式。

对于多语言代码库,数据库一次生成一种语言。 每种语言都有自己的唯一数据库架构。 该架构在提取过程中提供初始词法分析与通过 CodeQL 进行复杂分析之间的接口。

CodeQL 数据库包括两个主要表:

  • expressions 表包含在生成过程中 CodeQL 分析的源代码中的每个表达式对应的行。
  • statements 表包含 CodeQL 在构建过程中分析的源代码中的每个语句的一行。

CodeQL 库定义类,以便为每个表提供抽象层。 此层包括相关的辅助表 ExprStmt

潜在的 CodeQL 缺陷

代码扫描工作流中的数据库创建存在一些潜在的不足。 本部分专门讨论使用 GitHub CodeQL 动作。

需要使用 autobuild 的语言矩阵来生成矩阵中列出的每种已编译语言。 可以使用矩阵为编程语言、作系统或工具的多个受支持的版本创建作业。

如果不使用矩阵, autobuild 则尝试使用存储库中大多数源文件生成受支持的已编译语言。 在分析编译语言时(Go 除外),如果不在执行分析步骤之前提供显式命令生成代码,往往会导致分析失败。

该步骤的行为 autobuild 根据语言提取程序运行的操作系统而异。 该 autobuild 步骤尝试根据操作系统自动检测适用于该语言的构建方法。 此行为可能会导致编译语言的不可靠结果,并且通常会导致运行失败。

建议在代码扫描工作流文件中配置在分析之前运行的构建步骤,而不是让 autobuild 尝试构建编译型语言。 这样,工作流文件根据您的系统和项目的构建需求进行了调整,以实现更可靠的扫描。

您可以在 autobuild中阅读有关特定语言和 步骤的更多信息。

VS Code 扩展

只要使用的是 VS Code 1.39 或更高版本,就可以使用 Visual Studio Code (VS Code)和 CodeQL 扩展来编译和运行查询。 可以从 Visual Studio Code 市场 或下载 CodeQL VSIX 文件下载扩展。

该扩展使用在 PATH 中找到的已安装 CLI(如果可用)。 如果没有,扩展将自动为你管理对 CLI 可执行文件的访问。 自动管理可确保 CLI 与 CodeQL 扩展兼容。