Package URL
Package URL(purl)是一種標準字串,以生態系、命名空間、名稱與版本識別軟體套件,例如 pkg:npm/[email protected]。
最後更新:2026年11月11日
Package URL(purl)是一種軟體套件的標準識別碼,依照套件所屬生態系本身的命名方式來表示套件:pkg:type/namespace/name@version?qualifiers#subpath。它於 2025 年 12 月成為 Ecma 標準 ECMA-427(第 1 版,Ecma TC54),規格則維護於 package-url/purl-spec。
purl 的組成方式
每個 purl 都以 scheme pkg 開頭。type 是生態系或套件管理工具(npm、pypi、cargo、deb、maven 等)。namespace 是選用的分組,例如 npm scope、Maven group 或 Linux 發行版。接著是 name 與 version。qualifiers 補充生態系精確鎖定套件所需的資訊,例如架構或發行版的版本,subpath 則指向套件內部的位置。
pkg:npm/%40angular/[email protected]
pkg:pypi/[email protected]
pkg:cargo/[email protected]
pkg:deb/ubuntu/[email protected]+dfsg-1ubuntu2.1?arch=arm64&distro=noble
最後一個範例傳達的不只是「cpio 2.15」:它是 Ubuntu 為 Noble 版本在 arm64 上自行建置的版本。這一點很重要,因為發行版會將資安修正回移到自己的版本中,所以同一個上游版本,在某個發行版中可能有漏洞,在另一個發行版中卻已修正。
漏洞比對為何仰賴 purl
以套件為單位整理的資安公告資料庫,是透過生態系與名稱來辨識元件。OSV schema 要求每個受影響的套件都必須有 ecosystem 與 name,並將其 purl 欄位標為「選用但建議提供」;GitHub 的資安公告也是依生態系套件列出。當 SBOM 元件帶有 purl 時,工具就能將其與這些資安公告精確比對。如果沒有 purl,工具只能從名稱或 CPE 推測,甚至完全比對不到,漏洞也就不會被回報。
在我們比較過的一次 Yocto 建置中,建置系統自身的 SBOM 將數百個 Rust crate 僅列為附有下載位置的 .crate 檔案,沒有 pkg:cargo purl,因此這些 crate 無法與 Rust 資安公告比對(請參閱 Yocto 建置)。較新的 Yocto 版本會為 Cargo 與 Go 來源加上生態系 purl。
Package URL 與 CPE 的比較
| Package URL | CPE | |
|---|---|---|
| 由誰定義名稱 | 套件所屬的生態系 | NVD 的 CPE 字典 |
| 識別對象 | 套件登錄庫或發行版中的套件 | 產品,包括硬體與作業系統 |
| 格式 | pkg:type/namespace/name@version | cpe:2.3:part:vendor:product:version:... |
| 標準 | ECMA-427 | NISTIR 7695(CPE 2.3) |
| 使用者 | OSV、GitHub 資安公告、SBOM 工具 | NVD、許多掃描工具 |
| 常見的失誤 | vendored 或手動列出的程式碼缺少 purl | 廠商與產品名稱模糊;許多新 CVE 沒有 CPE 資料 |
經驗法則是:為每個有生態系的套件提供 purl,對於沒有生態系的項目,例如商業軟體、韌體與硬體,則使用 CPE。識別碼不一致是錯誤發現的主要原因之一,詳見如何減少漏洞雜訊。
SBOM 中的 Package URL
CycloneDX 與 SPDX 都會為每個元件記錄 purl。CISA 的 2026 Minimum Elements 指出,元件識別碼應使用通用識別碼,「例如 Common Platform Enumeration(CPE)與 Package-URL(PURL)」;德國的 BSI TR-03183-2 則要求每個元件在有此類識別碼時都必須提供。缺少 purl 是欄位品質的問題,而不是 SBOM 完整度的缺口:元件雖然有列出,但沒有任何資安公告資料庫能查詢到它。
CRACI 會為建置引入的每一個套件記錄 Package URL,包括 Yocto 建置中的每一個 Rust crate,因此其 SBOM 可以與資安公告比對。請參閱建置時 SBOM。