繁體中文(香港)
  • pnpm
  • security
  • dependencies
  • npm
  • yarn

使用 PNPM 升級傳遞依賴關係:修復安全漏洞而不破壞項目

修復安全漏洞可能是一項令人沮喪的任務,特別是當涉及到傳遞依賴關係時。學習如何在不影響直接依賴的情況下升級它們。

Gao
Gao
Founder

Stop wasting weeks on user auth
Launch secure apps faster with Logto. Integrate user auth in minutes, and focus on your core product.
Get started
Product screenshot

如今,安全漏洞在軟件開發中是一個常見的問題。幸運的是,我們有像 GitHub Dependabot 這樣的工具來幫助我們保持依賴項的最新狀態,通過自動檢測和拉取請求。

Dependabot

然而,它並不總是如預期般運行。由於某些依賴關係是傳遞的,這些工具可能難以升級它們,因為它們不知道變更的影響以及在出現衝突時應該做出何種決定。這些情況需要我們手動處理。

不起作用的方法

  • 官方命令如 pnpm up 會搞亂你的 pnpm-lock.yaml 文件。在撰寫本文時,仍有 相關問題 開放。
  • 安裝具有目標傳遞依賴關係的直接依賴的最新版本可能不起作用。如果直接依賴沒有升級版本定義,傳遞依賴關係將不會升級,因為它已在 pnpm-lock.yaml 文件中被解析和鎖定。

解決方案

在 PNPM 中,overrides 字段 是一個強大的功能,允許你覆蓋一些版本解析。 我們將使用此功能來升級傳遞依賴關係並使變更儘可能最小化。

讓我們以上述的 Dependabot 警報為例。它告訴我們 follow-redirects 包有一個安全漏洞,而修補版本是 1.15.6。然而,直接依賴 gatsby 使用的 axios 取決於 [email protected]

第 1 步:找出傳遞依賴關係

有很多方法可以定位傳遞依賴關係,但我建議使用最直接的方法:搜索 pnpm-lock.yaml 文件。

使用 "pnpm why" 呢?

pnpm why <package> 命令確實很有用。然而,在這種情況下,可能會讓你感到困惑。例如,當我運行 pnpm why follow-redirects 時,這是部分輸出:

事實上,pnpm-lock.yaml 文件中只有一個 follow-redirects 的解析。pnpm why 命令可能會向你展示多個依賴同一版本包的路徑。

第 2 步:添加覆蓋

最簡單的情況是 pnpm-lock.yaml 文件中只有一個解析。你可以直接將覆蓋添加到 package.json 文件中:

如果你在一個工作空間中,你應該將覆蓋添加到工作空間根目錄的 package.json 文件中。

第 3 步:應用變更

運行 pnpm install 以應用變更。我們可以看到 follow-redirects 包在 pnpm-lock.yaml 中被升級到 1.15.6,變更最小化。

現在你可以從 package.json 文件中刪除 overrides 字段來保持文件清潔。然後運行 pnpm install 再次驗證改變可以在沒有 overrides 字段的情況下被應用。

疑難排解

上述步驟是理想的情況。事情並不總是按預期進行。這裡有一些疑難排解的提示:

“overrides” 字段移除後版本恢復

如果依賴包具有固定版本或不包括目標版本的範圍,這可能會發生。查看依賴包的 package.json 文件,在本例中為 axios,看看是否如此。

如果是這樣,你需要將 overrides 字段保留在 package.json 文件中,直到依賴包升級版本定義。

傳遞依賴存在多個解析

隨著項目的增長,pnpm-lock.yaml 文件可能會浮動同一包的多個解析。例如,可能有兩個主要版本的同一包 foo

漏洞報告顯示 [email protected] 存在安全問題,已在 1.0.1 中修復,而 [email protected] 不受影響。我們不能簡單地對 foo 添加覆蓋:

假設 foo 遵循 語義化版本控制,我們可以這樣添加覆蓋:

這將僅將 [email protected] 升級到 1.0.1,並保持 [email protected] 不變。

結論

在 PNPM 支持直接升級傳遞依賴之前,利用 overrides 字段是一個很好的變通辦法,可以修復安全漏洞而不破壞項目。希望本文可以幫助你更有效地處理這些情況。在 Logto,我們使用這種方法來保持我們的依賴項最新且安全。