使用 VEX 建立例外

Vulnerability Exploitability eXchange (VEX) 是一種用於在軟體包或產品的上下文中記錄漏洞的標準格式。Docker Scout 支援 VEX 文件來為映象中的漏洞建立例外

注意

您還可以使用 Docker Scout Dashboard 或 Docker Desktop 建立例外。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 字串以 pkg:docker 型別字首開頭,後跟映象倉庫和版本(映象標籤或 SHA256 摘要)。與映象標籤(版本指定為 example/app:v1)不同,在 PURL 中,映象倉庫和版本由 @ 分隔。

--subcomponents
映象中易受攻擊包的 PURL。在此示例中,漏洞存在於 npm 包中,因此 --subcomponents PURL 是 npm 包名稱和版本(pkg:npm/express@4.17.1)的識別符號。

如果同一漏洞存在於多個包中,vexctl 允許您在一個 create 命令中多次指定 --subcomponents 標誌。

您還可以省略 --subcomponents,在這種情況下,VEX 宣告適用於整個映象。

--vuln
VEX 宣告解決的 CVE ID。
--status
這是漏洞的狀態標籤。它描述了軟體(--product)與 CVE(--vuln)之間的關係。OpenVEX 中狀態標籤的可能值為
  • 未受影響
  • 受影響
  • 已修復
  • 正在調查中

在此示例中,VEX 宣告斷言 Docker 映象“未受漏洞影響”。not_affected 狀態是唯一導致 CVE 抑制的狀態,其中 CVE 從分析結果中過濾掉。其他狀態對於文件編制很有用,但它們不適用於建立例外。有關所有可能的狀態標籤的更多資訊,請參閱 OpenVEX 規範中的狀態標籤

--justification
證明 not_affected 狀態標籤的合理性,說明產品為何不受漏洞影響。在此情況下,給出的理由是 vulnerable_code_not_in_execute_path,表示漏洞不能在產品使用時執行。

在 OpenVEX 中,狀態理由可以有以下五個可能值之一

  • 元件不存在
  • 易受攻擊的程式碼不存在
  • 易受攻擊的程式碼不在執行路徑中
  • 易受攻擊的程式碼無法被攻擊者控制
  • 已存在內聯緩解措施

有關這些值及其定義的更多資訊,請參閱 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 文件的更多資訊。

要了解有關 vexctl CLI 工具的可用標誌和語法的更多資訊以及如何安裝它,請參閱 vexctl GitHub 倉庫

驗證 VEX 文件

要測試您建立的 VEX 文件是否格式正確併產生預期結果,請使用 docker scout cves 命令並帶有 --vex-location 標誌,以使用 CLI 將 VEX 文件應用於本地映象分析。

以下命令使用 --vex-location 標誌呼叫本地映象分析,該分析包含指定位置的所有 VEX 文件。在此示例中,CLI 被指示在當前工作目錄中查詢 VEX 文件。

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

docker scout cves 命令的輸出顯示了結果,其中考慮了在 --vex-location 位置找到的任何 VEX 宣告。例如,狀態為 not_affected 的 CVE 將從結果中過濾掉。如果輸出似乎沒有考慮 VEX 宣告,則表明 VEX 文件可能以某種方式無效。

需要注意的事項包括

  • Docker 映象的 PURL 必須以 pkg:docker/ 開頭,後跟映象名稱。
  • 在 Docker 映象 PURL 中,映象名稱和版本由 @ 分隔。名為 example/myapp:1.0 的映象具有以下 PURL:pkg:docker/example/myapp@1.0
  • 記住要指定 author(它是 OpenVEX 中的必填欄位)
  • OpenVEX 規範描述瞭如何在 VEX 文件中使用 justificationimpact_statement 和其他欄位。以不正確的方式指定這些欄位會導致文件無效。請確保您的 VEX 文件符合 OpenVEX 規範。

將 VEX 文件附加到映象

建立 VEX 文件後,您可以透過以下方式將其附加到映象

VEX 文件一旦新增到映象就無法刪除。對於作為證明附加的文件,您可以建立一個新的 VEX 文件並將其再次附加到映象。這樣做會覆蓋之前的 VEX 文件(但不會刪除證明)。對於 VEX 文件已嵌入映象檔案系統中的映象,您需要重建映象才能更改 VEX 文X 文件。

證明

要將 VEX 文件作為證明附加,您可以使用 docker scout attestation add CLI 命令。在使用 VEX 時,使用證明是為映象附加例外推薦的選項。

您可以將證明附加到已推送到登錄檔的映象。您無需再次構建或推送映象。此外,將例外作為證明附加到映象意味著使用者可以直接從登錄檔檢查映象的例外。

要將證明附加到映象

  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-toto predicateType

映象檔案系統

如果您在構建映象之前提前知道例外情況,則將 VEX 文件直接嵌入映象檔案系統是一個不錯的選擇。而且相對容易;只需在 Dockerfile 中將 VEX 文件 COPY 到映象中即可。

這種方法的缺點是您以後無法更改或更新例外。映象層是不可變的,因此您放入映象檔案系統中的任何內容都將永遠存在。將文件作為證明附加可提供更好的靈活性。

注意

嵌入在映象檔案系統中的 VEX 文件不會被視為具有證明的映象。如果您的映象有**任何**證明,Docker Scout 將只在證明中查詢例外,而不會在映象檔案系統中查詢。

如果要使用嵌入在映象檔案系統中的 VEX 文件,則必須從映象中刪除證明。請注意,可能會自動為映象添加出處證明。為確保不向映象新增任何證明,您可以在構建映象時使用 --provenance=false--sbom=false 標誌顯式停用 SBOM 和出處證明。

要將 VEX 文件嵌入映象檔案系統,請在映象構建過程中將檔案 COPY 到映象中。以下示例演示瞭如何將構建上下文中 .vex/ 下的所有 VEX 文件複製到映象中的 /var/lib/db

# syntax=docker/dockerfile:1

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

VEX 文件的檔名必須與 *.vex.json 全域性模式匹配。檔案儲存在映象檔案系統上的哪個位置無關緊要。

請注意,複製的檔案必須是最終映象檔案系統的一部分。對於多階段構建,文件必須保留在最終階段。