# 使用 CodeQL 包自定义分析

可使用 CodeQL 包来运行由其他人维护的 CodeQL 查询，或共享你开发的 CodeQL 查询。

可以通过下载其他人创建的包并在代码库上运行这些包来自定义 CodeQL 分析。 有关详细信息，请参阅“[CodeQL 查询包](/zh/code-security/concepts/code-scanning/codeql/codeql-query-packs)”。

## 下载和使用 CodeQL 查询包

在使用 CodeQL 查询包分析数据库之前，必须从 GitHub Container registry 下载所需的任何包。 这可以通过使用 `--download` 标志作为 `codeql database analyze` 命令的一部分或运行 `codeql pack download` 来完成。 如果包不是公开可用，需要使用 GitHub App 或 personal access token 进行身份验证。 有关更多信息和示例，请参阅 [将 CodeQL 分析结果上传到GitHub](/zh/code-security/codeql-cli/getting-started-with-the-codeql-cli/uploading-codeql-analysis-results-to-github#uploading-results-to-github)。

| 选项                                                                                 |                                                                                                                                                                                                               必选                                                                                                                                                                                                               | Usage                                                                                                                                     |
| ---------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------------- |
| <code><span style="white-space: nowrap;">\<scope/name\@version:path></span></code> |                                                    <svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-check" aria-label="check icon" role="img"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg>                                                   | 使用以逗号分隔的列表指定要下载的一个或多个 CodeQL 查询包的作用域和名称。 （可选）包括要下载和解压缩的版本。 默认情况下，将下载此包的最新版本。 （可选）包括要运行的查询、目录或查询套件的路径。 如果未包括路径，则运行此包的默认查询。                 |
| <code><span style="white-space: nowrap;">--github-auth-stdin</span></code>         | <svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-x" aria-label="Optional" role="img"><path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path></svg> | 通过标准输入，将为对 GitHub App 的 REST API 进行身份验证而创建的 personal access token 或 GitHub 从机密存储库传递给 CLI。 如果命令有权访问使用此令牌设置的 `GITHUB_TOKEN` 环境变量，则不需要执行此操作。 |

> \[!NOTE]
> 如果你指定了要使用的特定版本的查询包，请注意你指定的版本最终可能会因过旧而无法被最新版本的 CodeQL 高效利用。 为了确保最佳性能，如果需要指定确切的查询包版本，应重新评估每次升级所使用的 CodeQL CLI 时要固定到的版本。
>
> 有关包兼容性的详细信息，请参阅 [CodeQL 查询包参考](/zh/code-security/reference/code-scanning/codeql/codeql-cli/codeql-query-packs#codeql-pack-compatibility)。

### 下载并使用查询包的基本示例

此示例运行包含 `codeql database analyze` 选项的 `--download` 命令来执行以下操作：

1. 下载最新版本的 `octo-org/security-queries` 包。
2. 下载与 1.0.1 版本`octo-org/optional-security-queries`的 \_\_ 包版本（在此情况下为 1.0.2 版本）。 有关 SemVer 兼容性的详细信息，请参阅 [npm 的语义化版本范围文档](https://github.com/npm/node-semver#ranges)。
3. 在 `octo-org/security-queries` 中运行所有默认查询。
4. 在 `queries/csrf.ql` 中仅运行查询 `octo-org/optional-security-queries`

```shell
$ echo $OCTO-ORG_ACCESS_TOKEN | codeql database analyze --download /codeql-dbs/example-repo \
    octo-org/security-queries \
    octo-org/optional-security-queries@~1.0.1:queries/csrf.ql \
    --format=sarif-latest --output=/temp/example-repo-js.sarif

> Download location: /Users/mona/.codeql/packages
> Installed fresh octo-org/security-queries@1.0.0
> Installed fresh octo-org/optional-security-queries@1.0.2
> Running queries.
> Compiling query plan for /Users/mona/.codeql/packages/octo-org/security-queries/1.0.0/potential-sql-injection.ql.
> [1/2] Found in cache: /Users/mona/.codeql/packages/octo-org/security-queries/1.0.0/potential-sql-injection.ql.
> Starting evaluation of octo-org/security-queries/query1.ql.
> Compiling query plan for /Users/mona/.codeql/packages/octo-org/optional-security-queries/1.0.2/queries/csrf.ql.
> [2/2] Found in cache: /Users/mona/.codeql/packages/octo-org/optional-security-queries/1.0.2/queries/csrf.ql.
> Starting evaluation of octo-org/optional-security-queries/queries/csrf.ql.
> [2/2 eval 694ms] Evaluation done; writing results to octo-org/security-queries/query1.bqrs.
> Shutting down query evaluator.
> Interpreting results.
```

### 直接下载 CodeQL 包

如果要在不立即运行 CodeQL 包的情况下进行下载，则可以使用 `codeql pack download` 命令。 如果要避免在运行 CodeQL 查询时访问 Internet，此选项非常有用。 运行 CodeQL 分析时，可以采用与上一示例相同的方式指定包、版本和路径：

```shell
echo $OCTO-ORG_ACCESS_TOKEN | codeql pack download <scope/name@version:path> <scope/name@version:path> ...
```

### 从多 CodeQL 容器注册表下载 GitHub 包

如果 CodeQL 包存在于多个容器注册表上，就必须指示 CodeQL CLI 在何处查找每个包。 有关详细信息，请参阅“[代码扫描的工作流配置选项](/zh/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#downloading-codeql-packs-from-github-enterprise-server)”。

## 指定要在 CodeQL 包中运行的查询

查询说明符由 `codeql database analyze` 和对一组查询进行操作的其他命令使用。
查询说明符的完整形式为 `scope/name@range:path`，其中：

* `scope/name` 是 CodeQL 包的限定名称。
* `range` 是[语义化版本范围](https://docs.npmjs.com/cli/v6/using-npm/semver#ranges)。
* `path` 是指向单个查询、包含查询的目录或查询套件文件的文件系统路径。

指定 `scope/name` 时，`range` 和 `path` 是可选的。 如果省略 `range`，则使用指定包的最新版本。 如果省略 `path`，则使用指定包的默认查询套件。

```
          `path` 可以是以下项之一：`.ql` 查询文件、包含一个或多个查询的目录或 `.qls` 查询套件文件。 如果省略包名称，则必须提供 `path`，它将相对于当前进程的工作目录进行解释。 不支持 glob 模式。
```

如果同时指定 `scope/name` 和 `path`，则 `path` 不能为绝对值。 它被视为相对于 CodeQL 包的根。

### 示例查询说明符

* `codeql/python-queries` - `codeql/python-queries` 包最新版本的默认查询套件中的所有查询。

* `codeql/python-queries@1.2.3` - `1.2.3` 包 `codeql/python-queries` 版本的默认查询套件中的所有查询。

* `codeql/python-queries@~1.2.3` - `codeql/python-queries` 包最新版本（>= `1.2.3` 且 < `1.3.0`）的默认查询套件中的所有查询。

* `codeql/python-queries:Functions` - `Functions` 包最新版本的 `codeql/python-queries` 目录中的所有查询。

* `codeql/python-queries@1.2.3:Functions` - `Functions` 包 1.2.3 版本的 `codeql/python-queries` 目录中的所有查询。

* `codeql/python-queries@1.2.3:codeql-suites/python-code-scanning.qls` - `codeql-suites/python-code-scanning.qls` 包 1.2.3 版本的 `codeql/python-queries` 目录中的所有查询。

* `suites/my-suite.qls` - 相对于当前工作目录的 `suites/my-suite.qls` 文件中的所有查询。

> \[!TIP]
> 标准 CodeQL 查询包的默认查询套件为 `codeql-suites/<lang>-code-scanning.qls`。 还可以在每个包的 `codeql-suites` 目录中找到其他几个有用的查询套件。 例如，`codeql/cpp-queries` 包包含以下查询套件：
>
> *

```
          `cpp-code-scanning.qls` - C++ 的标准代码扫描查询。 此包的默认查询套件。
```

> *

```
          `cpp-security-extended.qls` - C++ 的默认 `cpp-code-scanning.qls` 套件中的查询，以及低严重级别和低精度查询。
```

> *

```
          `cpp-security-and-quality.qls` - `cpp-security-extended.qls` 中的查询，以及可维护性和可靠性查询。
```

> 可以在 [CodeQL 存储库](https://github.com/github/codeql/tree/main/cpp/ql/src/codeql-suites)中查看这些查询套件的源。 其他语言的查询套件类似。

## 使用模型包来分析对自定义依赖项的调用

可以使用 `--model-packs` 选项，将已发布的模型包包含在 code scanning 分析中。 例如：

```shell
$ codeql database analyze /codeql-dbs/my-company --format=sarif-latest \
  --model-packs my-repo/my-java-model-pack \
  --output=/temp/my-company.sarif codeql/java-queries
```

在此示例中，标准查询包 `codeql/java-queries` 中的相关查询将使用模型包 `my-repo/my-java-model-pack` 中的依赖项信息，来检查调用这些依赖项的代码中的漏洞。

可以在分析中指定多个已发布的模型包。

有关编写自己的模型包的详细信息，请参阅 [创建并使用 CodeQL 包](/zh/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/creating-and-working-with-codeql-packs#creating-a-model-pack)。

### 关于发布的包

发布包用于分析时，`codeql pack create` 或 `codeql pack publish` 命令会验证内容是否完整，并向其中另外添加一些内容：

* （对于查询包）它所依赖的每个库包的副本，采用其开发的精确版本。 查询包的用户无需单独下载这些库包。

* （对于查询包）每个查询的预编译表示形式。 与在每次分析时编译查询的 QL 源相比，执行它们的速度更快。

其中大部分数据位于已发布包中名为 `.codeql` 的目录中，但预编译查询位于每个查询的 `.qlx` 源旁边带有 `.ql` 后缀的文件中。 使用已发布包中的查询分析数据库时，CodeQL 将加载这些文件，而不是 `.ql` 源。 如果需要修改\_已发布\_包的内容，请务必删除所有 `.qlx` 文件，因为它们可能会阻止 `.ql` 文件中的修改生效。