相依套件
什麼是遞移相依套件?
遞移相依套件是您的軟體因為另一個套件需要而使用的套件。您從未宣告過它,但它就在您出貨的內容裡,並帶有自己的漏洞與授權。本頁說明如何看見它們、修補它們,並證明每個版本納入了哪些套件。
更新日期
直接相依套件與遞移相依套件
直接相依套件是您在 manifest 中宣告的套件。遞移相依套件則是您的相依套件所宣告的套件,以及它們再往下宣告的套件,一路延伸到樹狀結構的最深處。套件管理工具在安裝時會解析整個樹狀結構,通常也會將結果記錄在鎖定檔(lockfile)中。
以一個只宣告了 express 這個套件的應用程式為例。執行 npm ls --all,就能看到這一行會帶進哪些內容:
my-app
└─┬ express ← 直接:由您宣告
├─┬ body-parser ← 遞移,第 1 層
│ └── raw-body ← 遞移,第 2 層
├── cookie ← 遞移,第 1 層
└─┬ send ← 遞移,第 1 層
└── mime-types ← 遞移,第 2 層 實際的樹狀結構更長。一般應用程式中的大多數套件都是這樣進來的,這代表您出貨的大部分程式碼是由套件管理工具挑選的,而不是您。
| 直接相依套件 | 遞移相依套件 | |
|---|---|---|
| 由誰選擇 | 您的團隊,在 manifest 中 | 套件管理工具,依據您相依套件的 manifest |
| 列在哪裡 | manifest 與 lockfile | lockfile(如果有的話) |
| 由誰控制版本 | 您 | 上層套件的版本範圍,除非您加以覆寫 |
| 如何修補漏洞 | 升級它 | 升級上層套件,或覆寫版本 |
為什麼遞移相依套件很重要
它們帶有與直接相依套件相同的風險,但能見度更低、可控性也更低。
- 漏洞。log4j 的零時差漏洞 Log4Shell 公開時,Google 的 Open Source Insights 團隊發現有 35,863 個 Maven Central 建置產物依賴受影響的 log4j 程式碼。其中約 7,000 個是直接依賴,大多數則是以遞移相依套件的形式引入,而且許多必須等到中間的某個套件先發布修正後才能修補。
- 供應鏈攻擊。xz utils 後門(CVE-2024-3094)觸及了 OpenSSH,而 OpenSSH 本身並不依賴 xz。數個 Linux 發行版會修補 OpenSSH 以支援 systemd 通知,而 libsystemd 依賴 liblzma,也就是 xz 提供的函式庫。
- 授權。每個遞移套件都有自己的授權。位於三層之下的 copyleft 授權,與您自行加入的授權同樣具有約束力。
- 破壞性變更。接受版本範圍的上層套件,會在下一次全新安裝時讓新的遞移版本進入,即使您的 manifest 完全沒有變動。
如何列出您的遞移相依套件
每個主要的套件管理工具都能輸出解析後的樹狀結構:
| 生態系 | 指令 |
|---|---|
| npm | npm ls --all |
| pnpm | pnpm list --depth Infinity |
| Python (uv) | uv tree |
| Python (pip) | pipdeptree |
| Go | go mod graph |
| Rust | cargo tree |
| Maven | mvn dependency:tree |
| Gradle | gradle dependencies |
若要找出單一套件為什麼會在那裡,可以查詢通往它的路徑:npm explain <package>、pnpm why、yarn why 或 cargo tree -i <crate>。若要運用這些路徑而不只是輸出它們,請參閱相依關係圖。
如何修補有漏洞的遞移相依套件
- 升級上層套件。找出引入該套件的直接相依套件,改用需要已修正版本的發布版本。這是最乾淨的修補方式,因為上層套件的維護者已經測試過。
- 更新 lockfile。如果上層套件的版本範圍已允許已修正的版本,只要更新 lockfile 中的項目即可,例如使用
cargo update -p <crate>或重新執行npm update。 - 覆寫版本。如果上層套件尚未發布修正,就自行強制指定版本:npm 與 pnpm 使用
overrides,Yarn 使用resolutions,pip 使用 constraints 檔案,或在go.mod中提高版本要求。請務必測試,因為上層套件從未針對該版本發布過。 - 替換或移除上層套件。如果以上方法都行不通,引入該套件的相依套件可能已不值得保留。
部分軟體組成分析工具會加入可達性分析,檢查您的程式碼是否真的會呼叫有漏洞的函式,藉此決定應優先採取哪一種修補方式。各種選項請參閱 SCA 工具比較。
為什麼 lockfile 無法說明全貌
大多數工具是根據鎖定檔建立它們對遞移相依套件的認知。當鎖定檔存在、保持最新,而且是建置唯一的安裝依據時,這種做法可行。但在 CI 中,情況往往並非如此:
- 沒有 lockfile。帶有版本範圍的
requirements.txt,或從未 commit 其 lockfile 的專案,每次建置都會重新解析,因此遞移版本可能在每次建置之間改變。 - 快取。CI 快取會還原先前執行時的套件,而不是重新取得,而快取內容不一定與目前的 lockfile 相符。請參閱 GitHub Actions 快取隱藏了什麼。
- 建置工具。linter、編譯器、程式碼產生器與設定步驟,會把它們各自的相依樹帶進建置中。它們不在您應用程式的 manifest 裡,卻能存取您的原始碼與機密。
- 安裝腳本與下載。套件的安裝腳本可以取得更多程式碼,建置步驟也可以直接下載二進位檔。兩者都不會在 lockfile 中留下項目。
要完整記錄哪些遞移相依套件進入了某個版本,唯一的方式是在該版本建置時進行記錄。建置時 SBOM 說明了記錄建置與事後掃描其檔案之間的差異。
遞移相依套件與 CRA
歐盟的 Cyber Resilience Act(CRA)要求製造商製作一份 SBOM,涵蓋「至少產品的頂層相依套件」(附件 I 第 II 部分第 1 點)。法規並未提及遞移相依套件,因此法律上的最低要求比許多指南所說的更低。但 CRA 也要求您識別並處理產品所含元件中的漏洞,而有漏洞的遞移套件正是其中之一。只涵蓋第一層的 SBOM,會讓您大部分的相依樹被排除在這個流程之外。詳情請參閱 CRA 的 SBOM 要求。
CRACI 如何追蹤遞移相依套件
CRACI 是一個記錄建置而非掃描建置的 GitHub Actions 執行器。在每個作業執行時,具備套件感知能力的代理伺服器會記錄作業在樹狀結構每一層取用的每個套件,包括從 CI 快取還原的套件。相較於以掃描器為基礎的工具,這能更完整地呈現實際使用中的相依套件。
- 涵蓋每一層,如實標示。每個作業的 SBOM 都帶有完整性狀態,讓您知道記錄何時無法看到全部內容。
- 樹狀結構一目了然。相依關係圖以多種檢視方式呈現 SBOM 的相依層級。
- 匯出內容包含遞移相依套件。CycloneDX 與 SPDX 匯出檔包含遞移相依套件,每個都附有其宣告的授權。
- 哪些建置受到影響。當新漏洞出現時,建置歷史會顯示哪些過往建置含有該漏洞套件(無論是直接或遞移相依),讓您知道出貨該套件的期間(請參閱 我們是否受到某個 CVE 影響?)。歷史記錄依您的保存期限而定,預設為 180 天。
- 政策關卡。含有特定 CVE 的建置,可以在出貨前遭到封鎖。
CRACI 不提供可達性分析。如果您需要知道程式碼是否會呼叫有漏洞的函式,請搭配具備此功能的 SCA 工具。請參閱 CRACI 的 SBOM 產生,或預約示範,記錄您自己的一次建置。
遞移相依套件:常見問題
什麼是遞移相依套件?
遞移相依套件是您的軟體因為另一個套件需要而使用的套件。如果您的應用程式依賴函式庫 A,而 A 依賴函式庫 B,那麼 B 就是您應用程式的遞移(或稱間接)相依套件。您從未宣告過它,但它會隨您的軟體一起出貨。
直接相依套件與遞移相依套件有什麼不同?
直接相依套件是您在 manifest(例如 package.json、pyproject.toml 或 go.mod)中宣告的套件。遞移相依套件則是您的直接相依套件在任一層所宣告的套件。直接相依套件由您選擇;遞移相依套件則由套件管理工具在解析樹狀結構時選擇。
transient dependency 和 transitive dependency 是一樣的嗎?
實務上是的。「transient dependency」是「transitive dependency」常見的誤用。正確的術語是 transitive,源自遞移關係:如果 A 依賴 B,而 B 依賴 C,那麼 A 就依賴 C。
如何修補遞移相依套件中的漏洞?
如果引入該套件的直接相依套件已有包含修正版本的發布版本,請先升級它。若沒有,請使用套件管理工具的覆寫機制(例如 npm overrides、Yarn resolutions 或 pip constraints 檔案)強制指定已修正的版本,並測試上層套件是否仍能正常運作。
如何列出所有遞移相依套件?
每個套件管理工具都能輸出解析後的樹狀結構:npm ls --all、pnpm list --depth Infinity、uv tree 或 pipdeptree、go mod graph、cargo tree、mvn dependency:tree 或 gradle dependencies。若要知道正式環境建置實際安裝了什麼,請記錄建置本身。
歐盟 Cyber Resilience Act 是否要求 SBOM 包含遞移相依套件?
法規將最低要求訂為「至少產品的頂層相依套件」(附件 I 第 II 部分第 1 點)。法規並未提及遞移相依套件,但有漏洞的遞移套件仍然存在於您的產品中,而 CRA 要求您處理所出貨元件中的漏洞。