不破壞依賴樹的情況下修復間接漏洞
?修復間接漏洞是一項復雜、乏味且坦率地說是沒有人真正想接觸的無聊任務。當然,有很多方法可以手動完成,但是否可以自動完成而將破壞更改的風險降至最低?
布滿脆弱樹木的森林
那么,你甚至從哪里開始呢?
首先,需要有一種方法來修復漏洞,對于間接依賴而言,這種方法是行不通的。其次,它需要以安全的方式完成,或者沒有任何破壞。
你看,間接依賴關系是在依賴關系樹的深處引入的,要得到你想要的確切版本是非常棘手的。正如 Debricked 的研發主管曾經說過的那樣,“你正在通過玩弄你的直接依賴項并祈禱 Torvalds 解決正確的間接包來轉動旋鈕。當 Torvalds 對你有利時,你必須犧牲一些云存儲給叔叔Bob 確保更新不會破壞您的應用程序。”
換句話說,確實應該有一種更簡單、壓力更小的方法來做到這一點。
在本文中,我們將引導您了解如何手動解決傳遞性漏洞,并在最后向您展示 Debriked 解決方案,它允許您自動完成。如果您真的只是對解決方案感興趣,我建議您開始滾動。
對依賴樹進行精確手術
在圖數據庫項目的研究階段,或者說,今天 Debricked 如何以光速修復您的開源漏洞,團隊偶然發現了一些解釋如何修復 NPM 中的間接漏洞的文章。
如文章所述,`minimist` 軟件包受漏洞影響,即CVE-2021-44906和CVE-2020-7598。
這些都是“原型污染”漏洞,這意味著沒有正確清理參數。幸運的是,`minimist` 的維護者在 1.2.6 版本中修復了這些漏洞。
不幸的是,`mocha` 版本 7.1.0 解決了`minimist` 0.0.8,這是在這些漏洞的易受攻擊范圍內。正如本文作者所建議的,可以通過幾種不同的方式修復這些漏洞。
突破性的變化?
第一個建議是簡單地觸發所有“間接依賴項”的更新,這意味著我們實際上不會更改 `mocha` 的版本。要執行此更新,只需運行“npm update”,刪除你的“npm.lock”文件,然后運行“npm install”。這將使用您的間接依賴項的最新可能版本(根據約束)重新生成依賴項樹。使用這種方法,破壞更改的風險非常低,因為您實際上不會更新任何根依賴項,而只是更新您的間接依賴項。
當包的功能或接口不向前兼容時,就會發生重大更改,這意味著包的更新可能會導致您的應用程序中斷。常見的重大更改是類/函數刪除、函數參數更改或許可證更改(注意那個!)。
但生活并不總是那么容易,樹的這種簡單更新并不能解決漏洞。問題是 `mkdirp`實際上已將他們的 `minimist` 版本鎖定為 0.0.8。這意味著 `mkdirp` 的貢獻者已經得出結論,他們與較新版本的 `minimist` 不兼容,并且強制更新 `minimist` 可能會在 `mkdirp` 和 `minimist` 之間引入破壞性更改。
應該使用什么版本的 `mocha`,進而在不破壞依賴關系樹的情況下滴流到安全版本的 `minimist`?
什么圖算法可以解決這個問題?NPM 如何解決依賴關系可能有點復雜,因為它們可以“拆分”依賴關系樹。這意味著它們可以擁有一個依賴項的多個版本,以確保我們始終擁有一棵兼容的樹。為了解決這個漏洞,我們需要通過更新所有可以滲透到 `minimist` 的根來確保 `minimist` 的所有實例都是安全的。
用于解決此問題的算法稱為“所有最大路徑安全”。通過遍歷依賴圖并保持最大版本,同時在每個交叉點修剪該包的所有其他版本,我們可以創建依賴樹的近似表示。如果近似值是安全的,那意味著我們真正的樹也是安全的!
通過對“mocha”的所有潛在版本執行此算法,我們找到了修復此漏洞的最小升級。為了獲得我們想要的算法速度,團隊必須構建一個自定義的Neo4j 程序,它可以在約 150 毫秒內處理搜索超過 100 個根版本,搜索深度為 30+。速度快吧?
在這種情況下,我們不必搜索很遠……因為 `mocha` 的 7.1.1 是安全的!這只是一個補丁更新,這表明破壞更改的風險非常低。對于不太復雜的情況(如本例),“npm audit”可以幫助您使用他們出色的“npm audit fix”命令。