使用 VEX 建立例外

弱點可利用性交換 (VEX) 是一種標準格式,用於記錄軟體套件或產品的弱點。Docker Scout 支援 VEX 文件,以便為映像檔中的弱點建立例外

**注意**

您也可以使用 Docker Scout 儀表板或 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 鏡像的套件網址 (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 中狀態標籤的可能值為
  • not_affected(未受影響)
  • affected(受影響)
  • fixed(已修復)
  • under_investigation(調查中)

在本範例中,VEX 陳述式斷言 Docker 鏡像 not_affected(未受影響)於漏洞。not_affected 狀態是唯一導致 CVE 抑制的狀態,其中 CVE 會從分析結果中過濾掉。其他狀態可用於記錄目的,但它們不適用於建立例外。有關所有可能狀態標籤的更多資訊,請參閱 OpenVEX 規格中的 狀態標籤狀態理由JSON 文件範例

以下是此命令產生的 OpenVEX JSON

理解 VEX 文件的結構可能有點複雜。OpenVEX 規格vexctl GitHub 儲存庫驗證 VEX 文件

要測試您建立的 VEX 文件是否格式正確並產生預期結果,請使用帶有 --vex-location 旗標的 docker scout cves 命令,將 VEX 文件套用至使用 CLI 的本地鏡像分析。

以下命令會叫用本地鏡像分析,其中包含指定位置中的所有 VEX 文件,使用 --vex-location 旗標。在本範例中,CLI 被指示在目前工作目錄中尋找 VEX 文件。

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 文件附加到映像檔

    建立 VEX 文件後,您可以透過以下方式將其附加至您的鏡像

    您無法在將 VEX 文件新增至鏡像後將其移除。對於作為證明附加的文件,您可以建立新的 VEX 文件並再次將其附加至鏡像。這樣做會覆蓋先前的 VEX 文件(但不會移除證明)。對於 VEX 文件已嵌入鏡像檔案系統的鏡像,您需要重建鏡像才能更改 VEX 文件。

    證明

    要將 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 萬用字元模式。將檔案儲存在鏡像檔案系統中的哪個位置並不重要。

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