2026 年每日通報的 CVE 數量比前一年多 131%。

SBOM

SBOM 範例

了解 SBOM 最快的方法,就是讀一份。以下以 CycloneDX 與 SPDX 兩種格式呈現同一個小型應用程式,並說明每個欄位的意義、品質不佳的 SBOM 長什麼樣子,以及如何檢查您自己的 SBOM。

更新日期

這些範例中的應用程式

兩個檔案描述的都是 example-api 2.4.0,這是一個示意用的 Node.js 服務,只有一個直接相依套件 express。Express 又相依於 accepts,因此範例中也包含一個遞移相依套件。真實 Express 應用程式的 SBOM 會列出更多元件,但結構相同。

CycloneDX SBOM 範例

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
  "version": 1,
  "metadata": {
    "timestamp": "2026-10-30T09:00:00Z",
    "lifecycles": [{ "phase": "build" }],
    "tools": {
      "components": [
        { "type": "application", "name": "example-sbom-tool", "version": "1.0.0" }
      ]
    },
    "component": {
      "type": "application",
      "bom-ref": "example-api",
      "name": "example-api",
      "version": "2.4.0"
    }
  },
  "components": [
    {
      "type": "library",
      "bom-ref": "pkg:npm/[email protected]",
      "name": "express",
      "version": "4.21.2",
      "purl": "pkg:npm/[email protected]",
      "licenses": [{ "license": { "id": "MIT" } }]
    },
    {
      "type": "library",
      "bom-ref": "pkg:npm/[email protected]",
      "name": "accepts",
      "version": "1.3.8",
      "purl": "pkg:npm/[email protected]",
      "licenses": [{ "license": { "id": "MIT" } }]
    }
  ],
  "dependencies": [
    { "ref": "example-api", "dependsOn": ["pkg:npm/[email protected]"] },
    { "ref": "pkg:npm/[email protected]", "dependsOn": ["pkg:npm/[email protected]"] }
  ]
}
欄位 它告訴您什麼
specVersion 檔案使用的格式版本,讓工具能夠解析。
serialNumber、version 這是哪一份 SBOM,以及它的第幾個修訂版。
metadata.lifecycles SBOM 產生的時機。此處為建置期間。
metadata.tools 由哪個工具產生。兩個工具對同一個 commit 的回報可能不同。
metadata.component SBOM 所描述的產品。
purl 套件 URL,讓工具能將元件與資安公告比對的識別碼。
licenses 元件宣告的授權。
dependencies 誰帶入了誰。正是這個欄位讓 accepts 以遞移相依套件的身分顯現出來。

SPDX SBOM 範例

{
  "spdxVersion": "SPDX-2.3",
  "dataLicense": "CC0-1.0",
  "SPDXID": "SPDXRef-DOCUMENT",
  "name": "example-api-2.4.0",
  "documentNamespace": "https://example.com/spdx/example-api-2.4.0",
  "creationInfo": {
    "created": "2026-10-30T09:00:00Z",
    "creators": ["Tool: example-sbom-tool-1.0.0"]
  },
  "packages": [
    {
      "name": "example-api",
      "SPDXID": "SPDXRef-Package-example-api",
      "versionInfo": "2.4.0",
      "downloadLocation": "NOASSERTION"
    },
    {
      "name": "express",
      "SPDXID": "SPDXRef-Package-express",
      "versionInfo": "4.21.2",
      "downloadLocation": "NOASSERTION",
      "licenseDeclared": "MIT",
      "externalRefs": [
        {
          "referenceCategory": "PACKAGE-MANAGER",
          "referenceType": "purl",
          "referenceLocator": "pkg:npm/[email protected]"
        }
      ]
    },
    {
      "name": "accepts",
      "SPDXID": "SPDXRef-Package-accepts",
      "versionInfo": "1.3.8",
      "downloadLocation": "NOASSERTION",
      "licenseDeclared": "MIT",
      "externalRefs": [
        {
          "referenceCategory": "PACKAGE-MANAGER",
          "referenceType": "purl",
          "referenceLocator": "pkg:npm/[email protected]"
        }
      ]
    }
  ],
  "relationships": [
    {
      "spdxElementId": "SPDXRef-DOCUMENT",
      "relationshipType": "DESCRIBES",
      "relatedSpdxElement": "SPDXRef-Package-example-api"
    },
    {
      "spdxElementId": "SPDXRef-Package-example-api",
      "relationshipType": "DEPENDS_ON",
      "relatedSpdxElement": "SPDXRef-Package-express"
    },
    {
      "spdxElementId": "SPDXRef-Package-express",
      "relationshipType": "DEPENDS_ON",
      "relatedSpdxElement": "SPDXRef-Package-accepts"
    }
  ]
}

資訊相同,只是編排方式不同。SPDX 保有一份 packages 清單,並在 relationships 中說明項目之間的每一個關聯。licenseDeclared 是套件對自身的描述,而當工具不知道時,downloadLocation 可能為 NOASSERTION。兩種格式除了編排之外還有哪些差異,請參閱 CycloneDX 與 SPDX 比較。

品質不佳的 SBOM 長什麼樣子

檔案可能格式正確,卻幾乎毫無用處。請留意以下幾點:

  • 沒有相依關係。扁平的清單只能告訴您某個套件存在,卻無法告訴您是什麼帶入了它,而這正是修正遞移相依套件所需要的資訊。
  • 沒有套件 URL。少了 purl 這類識別碼,將元件與資安公告比對就只能靠名稱猜測。
  • 缺少授權。許多欄位留為 NOASSERTION,代表這份 SBOM 無法回答授權相關問題。
  • 元件數量少得可疑。大型應用程式只有寥寥幾個元件,通常代表只列了直接相依套件,或只列了某個 lockfile 宣告的內容。
  • 沒有說明何時與如何產生。沒有工具與產生脈絡,您就無法判斷這份 SBOM 可信賴的涵蓋範圍。
  • 對缺漏隻字未提。好的 SBOM 會說明它看不到什麼。多數檔案就這樣結束,讀者便以為內容是完整的。

如何檢查您自己的 SBOM

  1. 驗證格式。以對應其格式與版本的結構描述驗證工具檢查,因為無法解析檔案的工具也就無法使用它。
  2. 檢查欄位。與 2026 Minimum Elements 或客戶要求的清單比對。
  3. 搜尋您知道的東西。挑選一個遞移相依套件、一個來自基礎映像檔的套件和一個建置工具,看看其中哪些有出現。
  4. 比較兩個來源。以不同方法再產生一份 SBOM,觀察兩者的差異。一份檔案中多出的每個元件,都是對另一份檔案的疑問。

每項檢查與 NTIA、CISA 及 BSI 欄位清單的對應,請參閱 SBOM 品質檢查清單。

來自 CRACI 的建置時 SBOM

CRACI 匯出相同的格式。不同的是內容的來源:它記錄每個 GitHub Actions 作業取用了什麼,因此 SBOM 中的每個元件都確實被帶入了建置,而從 CI 快取還原的套件也會如實標示。工作流程執行的 GitHub Actions 也會列為元件,並鎖定在所使用的 commit。每個作業的 SBOM 也帶有完整性狀態,因此缺漏會被明確說明,而不是留給您自己去發現。請參閱建置時 SBOM 產生,或SBOM 工具比較。

SBOM 範例:常見問題

SBOM 長什麼樣子?

通常是 JSON 檔案,有時是 XML。它一開始是 SBOM 本身的資料,例如工具與時間戳記,接著列出每個元件的名稱、版本、識別碼與授權,最後描述元件之間的相依關係。

SBOM 是 JSON 檔案嗎?

通常是,因為 JSON 是 CycloneDX 與 SPDX 最廣泛使用的編碼方式。兩種格式也都有其他編碼方式,SPDX 另外還有 tag-value 文字格式。

SBOM 中的 purl 是什麼?

purl(package URL,套件 URL)是套件的標準識別碼,例如 pkg:npm/[email protected]。它以一個字串標示生態系、套件與版本,讓工具能可靠地將元件與漏洞資料比對。

一份 SBOM 應該有多少個元件?

沒有標準答案,但應該包含遞移相依套件,而遞移相依套件的數量通常遠多於直接相依套件。大型應用程式的元件少得出奇,通常代表工具只看到了其中一部分。

可以查看開源專案的 SBOM 嗎?

有時可以。有些專案會隨版本發布一併公開 SBOM,而 GitHub 也能從儲存庫的相依關係圖匯出一份。這份匯出反映的是儲存庫宣告的內容,而不是某次特定建置實際使用的內容。

將您的 SBOM 與記錄而得的 SBOM 比較

在 CRACI 上執行一個 GitHub Actions 工作流程,看看您目前的 SBOM 漏列了哪些元件。

預約示範