使用 VEX 创建异常

漏洞利用换 (VEX) 是 记录软件包或产品上下文中的漏洞。 Docker Scout 支持 VEX 文档为镜像中的漏洞创建例外

注意

您还可以使用 Docker Scout Dashboard 或 Docker 创建异常 桌面。GUI 提供了一个用户友好的界面,用于创建异常。 而且,可以轻松管理多个镜像的异常。它还允许您 为多个镜像或整个组织创建例外,所有这些都在 一次。有关更多信息,请参阅使用 GUI 创建例外

先决条件

要使用 OpenVEX 文档创建异常,您需要:

  • 最新版本的 Docker Desktop 或 Docker Scout CLI 插件
  • vexctl 命令行工具。
  • 必须启用 containerd 镜像存储
  • 对存储镜像的注册表存储库的写入权限

VEX 简介

VEX 标准由美国的一个工作组定义 网络安全和基础设施安全局 (CISA)。VEX 的核心是 可利用性评估。这些评估描述了给定 产品的 CVE。VEX 中可能的漏洞状态是:

  • 不受影响:此漏洞无需修复。
  • 受影响:建议采取措施来修复或解决此漏洞。
  • 已修复:这些产品版本包含针对该漏洞的修复程序。
  • 正在调查中:目前尚不清楚这些产品版本是否受此漏洞的影响。将在以后的版本中提供更新。

VEX 有多种实现和格式。Docker Scout 支持 OpenVex 实现。无论 具体实现,核心思想是一样的:提供一个框架 用于描述漏洞的影响。VEX 的关键组件 的实现包括:

VEX 文档
一种用于存储 VEX 语句的安全通告。 文档的格式取决于具体的实现。
VEX 声明
描述产品中漏洞的状态, 它是否可利用,以及是否有办法修复问题。
理由和影响
根据漏洞状态,语句包括理由 或影响声明,描述产品受到影响或未受到影响的原因。
操作语句
描述如何修复或缓解漏洞。

vexctl 示例

以下示例命令创建一个 VEX 文档,说明:

  • 本 VEX 文档描述的软件产品是 Docker 镜像example/app:v1
  • 该镜像包含 npm 软件包express@4.17.1
  • npm 包受到已知漏洞的影响:CVE-2022-24999
  • 该镜像不受 CVE 的影响,因为易受攻击的代码永远不会 在运行此镜像的容器中执行
$ vexctl create \
  --author="author@example.com" \
  --product="pkg:docker/example/app@v1" \
  --subcomponents="pkg:npm/express@4.17.1" \
  --vuln="CVE-2022-24999" \
  --status="not_affected" \
  --justification="vulnerable_code_not_in_execute_path" \
  --file="CVE-2022-24999.vex.json"

以下是此示例中选项的说明:

--author
VEX 文档作者的电子邮件。
--product
Docker 镜像的包 URL (PURL)。PURL 是一种标识符 对于采用标准化格式的镜像,在 PURL 规范中定义。

Docker 镜像 PURL 字符串以类型前缀开头,后跟 镜像存储库和版本(镜像标签或 SHA256 摘要)。与 image 标记,其中版本的指定方式如 ,在 PURL 中, 镜像存储库和版本由 .pkg:dockerexample/app:v1@

--subcomponents
镜像中易受攻击的软件包的 PURL。在此示例中, 漏洞存在于 npm 包中,因此 PURL 是 npm 包名称和版本 () 的标识符。--subcomponentspkg:npm/express@4.17.1

如果多个软件包中存在相同的漏洞,则允许您 为单个命令多次指定 flag。vexctl--subcomponentscreate

您也可以省略 ,在这种情况下,VEX 语句适用 到整个镜像。--subcomponents

--vuln
VEX 语句处理的 CVE 的 ID。
--status
这是漏洞的状态标签。这描述了 软件 () 和 CVE () 之间的关系。 OpenVEX 中状态标签的可能值为:--product--vuln
  • not_affected
  • affected
  • fixed
  • under_investigation

在此示例中,VEX 语句断言 Docker 镜像是漏洞造成的。状态是唯一的 状态,这会导致 CVE 抑制,其中 CVE 将从 分析结果。其他状态可用于文档目的, 但它们不适用于创建异常。有关所有 可能的状态标签,请参阅 OpenVEX 规范中的状态标签not_affectednot_affected

--justification
证明状态标签的合理性,告知产品未对齐的原因 受漏洞影响。在这种情况下,给出的理由是 ,表示漏洞 不能像产品使用的那样执行。not_affectedvulnerable_code_not_in_execute_path

在 OpenVEX 中,状态理由可以具有以下五个可能的值之一:

  • component_not_present
  • vulnerable_code_not_present
  • vulnerable_code_not_in_execute_path
  • vulnerable_code_cannot_be_controlled_by_adversary
  • inline_mitigations_already_exist

有关这些值及其定义的更多信息,请参阅 OpenVEX 规范中的状态理由

--file
VEX 文档输出的文件名

示例 JSON 文档

以下是此命令生成的 OpenVEX JSON:

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://openvex.dev/docs/public/vex-749f79b50f5f2f0f07747c2de9f1239b37c2bda663579f87a35e5f0fdfc13de5",
  "author": "author@example.com",
  "timestamp": "2024-05-27T13:20:22.395824+02:00",
  "version": 1,
  "statements": [
    {
      "vulnerability": {
        "name": "CVE-2022-24999"
      },
      "timestamp": "2024-05-27T13:20:22.395829+02:00",
      "products": [
        {
          "@id": "pkg:docker/example/app@v1",
          "subcomponents": [
            {
              "@id": "pkg:npm/express@4.17.1"
            }
          ]
        }
      ],
      "status": "not_affected",
      "justification": "vulnerable_code_not_in_execute_path"
    }
  ]
}

了解 VEX 文档的结构可能有点困难 口。OpenVEX 规范描述了文档的格式和所有可能的属性,以及 语句。有关完整详细信息,请参阅规格以了解更多信息 关于可用字段以及如何创建格式正确的 OpenVEX 文档。

要了解有关 CLI 工具的可用标志和语法的更多信息,以及 如何安装,请参考 vexctl GitHub 仓库vexctl

验证 VEX 文件

要测试您创建的 VEX 文档是否格式正确并生成 预期结果,使用带有标志的命令通过 CLI 将 VEX 文档应用于本地镜像分析。docker scout cves--vex-location

以下命令调用包含所有 VEX 的本地镜像分析 documents 在指定位置。在这个 example,指示 CLI 在当前工作中查找 VEX 文档 目录。--vex-location

$ docker scout cves <IMAGE> --vex-location .

该命令的输出显示任何 VEX 的结果 在 location 下找到的语句被纳入 结果。例如,分配了状态 的 CVE 将被筛选掉 从结果中。如果输出似乎没有将 VEX 语句放入 帐户,这表明 VEX 文档在某些 道路。docker scout cves--vex-locationnot_affected

需要注意的事项包括:

  • Docker 镜像的 PURL 必须以 开头,后跟镜像名称。pkg:docker/
  • 在 Docker 镜像 PURL 中,镜像名称和版本由 . 名为 的镜像具有以下 PURL: 。@example/myapp:1.0pkg:docker/example/myapp@1.0
  • 请记住指定一个(这是 OpenVEX 中的必填字段)author
  • OpenVEX 规范描述了 以及何时使用 、 和 VEX 文件。以不正确的方式指定这些会导致无效的 公文。确保您的 VEX 文档符合 OpenVEX 规范。justificationimpact_statement

将 VEX 文档附加到镜像

创建 VEX 文档后, 您可以通过以下方式将其附加到镜像:

一旦添加 VEX 文档,就无法从镜像中删除它。为 作为证明附加的文档,您可以创建新的 VEX 文档,并且 再次将其附加到镜像。这样做将覆盖以前的 VEX 文档 (但它不会删除证明)。对于 VEX 文档具有 嵌入到镜像的文件系统中,您需要将镜像重新构建为 更改 VEX 文档。

证明

要附加 VEX 文档作为证明,您可以使用 CLI 命令。使用证明是 使用 VEX 时为镜像附加异常。docker scout attestation add

您可以将证明附加到已推送到 注册表。您无需再次构建或推送镜像。此外,具有 作为证明附加到镜像的异常意味着消费者可以 直接从注册表检查镜像的异常。

要将认证附加到镜像:

  1. 构建镜像并将其推送到注册表。

    $ docker build --provenance=true --sbom=true --tag <IMAGE> --push .
    
  2. 将异常作为证明附加到镜像。

    $ docker scout attestation add \
      --file <cve-id>.vex.json \
      --predicate-type https://openvex.dev/ns/v0.2.0 \
      <IMAGE>
    

    此命令的选项包括:

    • --file:VEX 文档的位置和文件名
    • --predicate-type:OpenVEX 的 in-totopredicateType

镜像文件系统

如果 在构建镜像之前,您需要提前了解异常情况。而且它是 相对容易;只需将 VEX 文档复制到 Dockerfile 中的镜像。COPY

这种方法的缺点是您无法更改或更新 exception 的 intent 值。镜像层是不可变的,因此您放入镜像的 filesystem 永远存在。将文档作为证明附加可提供更好的灵活性。

注意

镜像文件系统中嵌入的 VEX 文档不考虑用于镜像 有证明的。如果您的镜像有任何证明,Docker Scout 将仅在证明中查找异常,而不在镜像中查找 文件系统。

如果要使用嵌入在镜像文件系统中的 VEX 文档,请 必须从镜像中删除证明。请注意,出处证明 可能会自动为镜像添加。确保没有证明 添加到镜像中,您可以显式禁用 SBOM 和 Provenance 在以下情况下使用 和 标志的证明 构建镜像。--provenance=false--sbom=false

要将 VEX 文档嵌入到镜像文件系统中,请将该文件嵌入到镜像中 作为镜像构建的一部分。以下示例显示了如何复制所有 VEX 文档 (documents) 下的 build 上下文中的 image 中。COPY.vex//var/lib/db

# syntax=docker/dockerfile:1

FROM alpine
COPY .vex/* /var/lib/db/

VEX 文档的文件名必须与 glob 模式匹配。 将文件存储在镜像文件系统上的哪个位置并不重要。*.vex.json

请注意,复制的文件必须是最终镜像的文件系统的一部分。 对于多阶段构建,文档必须保留在最后阶段。