保護軟體供應鏈的最佳做法
開放原始碼無處不在。 它位於許多專屬的程式代碼基底和社群專案中。 對於組織和個人來說,今天的問題是,您是或不是使用開放原始碼程序代碼,而是您使用的開放原始碼碼,以及多少。
如果您不知道軟體供應鏈中的內容,其中一個相依性中的上游弱點可能是致命的,讓您和您的客戶容易受到潛在危害。 在本檔中,我們將深入探討「軟體供應鏈」一詞的意義、為何重要,以及如何使用最佳做法協助保護您的項目供應鏈。
相依性
軟體供應鏈一詞是用來參考進入您軟體的所有專案,以及其來自何處。 這是軟體供應鏈相依性相依性的相依性和屬性。 相依性是軟體執行所需的專案。 它可以是程式代碼、二進制檔或其他元件,以及它們的來源,例如存放庫或套件管理員。
其中包含撰寫程式代碼的人員、參與程式代碼時,如何檢閱其安全性問題、已知弱點、支援的版本、授權資訊,以及任何在程式的任何時間點觸及它的內容。
您的供應鏈也包含堆疊以外的其他部分,例如您的組建和封裝腳本,或執行應用程式所依賴基礎結構的軟體。
弱點
目前,軟體相依性十分普遍。 您的專案通常會針對您不需要自行撰寫的功能使用數百個開放原始碼相依性。 這可能表示您的應用程式大部分是由您未撰寫的程式代碼所組成。
第三方或開放原始碼相依性的可能弱點可能是您無法像您所撰寫的程式代碼一樣嚴格控制相依性,這可能會在您的供應鏈中產生潛在的安全性風險。
如果其中一個相依性有弱點,您也有弱點。 這可能是可怕的,因為您的其中一個相依性可能會變更,而您甚至不知道。 即使弱點目前存在於相依性中,但無法利用,未來仍可加以利用。
能夠利用數千個開放原始碼開發人員和連結庫作者的工作,表示成千上萬的陌生人可以有效地為您的生產程序代碼做出貢獻。 透過軟體供應鏈,您的產品會受到未修補的弱點、無辜的錯誤,甚至是針對相依性的惡意攻擊所影響。
供應鏈洩露
供應鏈的傳統定義來自製造:這是製作和提供東西所需的程序鏈結。 它包括規劃、材料供應、製造和零售。 軟體供應鏈類似,除了材料之外,它是程序代碼。 它不是製造,而是開發。 程序代碼不是從地面挖掘礦石,而是從供應商、商業或 開放原始碼 來源,一般而言,開放原始碼程式代碼來自存放庫。 從存放庫新增程式代碼表示您的產品相依於該程序代碼。
當惡意代碼故意新增至相依性時,就會發生軟體供應鏈攻擊的一個範例,使用該相依性供應鏈將程式碼散發給受害者。 供應鏈攻擊是真實的。 有許多方法可以攻擊供應鏈,從直接將惡意代碼插入為新參與者,到接管參與者的帳戶,而不需要其他人注意到,甚至危害簽署密鑰來散發不屬於相依性的軟體。
軟體供應鏈攻擊本身很少是最終目標,而是攻擊者插入惡意代碼或為未來存取提供後門的機會的開始。
未修補的軟體
今天使用 開放原始碼 很重要,預計不會很快放緩。 假設我們不會停止使用開放原始碼軟體,供應鏈安全性的威脅是未修補的軟體。 知道這一點,如何解決專案相依性有弱點的風險?
- 瞭解您的環境中的內容。 這需要探索您的相依性和任何可轉移的相依性,以了解這些相依性的風險,例如弱點或授權限制。
- 管理您的相依性。 探索到新的安全性弱點時,您必須判斷是否受到影響,如果是的話,請更新為最新版本和安全性修補程式。 請務必檢閱引進新相依性的變更,或定期稽核較舊的相依性。
- 監視您的供應鏈。 這是藉由稽核您已就地管理相依性的控件。 這可協助您針對相依性強制執行更嚴格的條件。
我們將涵蓋 NuGet 和 GitHub 提供的各種工具和技術,您目前可以使用這些工具和技術來解決專案內的潛在風險。
瞭解您的環境中的內容
具有已知弱點的套件
📦 套件取用者 | 📦🖊 套件作者
.NET 8 和 Visual Studio 17.8 新增 NuGetAudit,這會在還原期間警告具有已知弱點的直接套件。 .NET 9 和 Visual Studio 17.12 已變更預設值,以警告有關可轉移套件的警告。
NuGetAudit 需要來源來提供已知的弱點資料庫,因此如果您未使用 nuget.org 做為套件來源,您應該將其新增為 稽核來源。
在 NuGet 警告您時,就會公開知道弱點。 攻擊者可以使用此公開洩漏來針對尚未修補其應用程式的目標開發攻擊。 因此,當您收到專案正在使用的套件有已知弱點的警告時,您應該快速採取動作。
NuGet 相依性圖表
📦 套件取用者
您可以直接查看個別項目檔,以檢視專案中的 NuGet 相依性。
這通常位於兩個位置的其中一個:
packages.config
– 位於專案根目錄中。<PackageReference>
– 位於項目檔中。
根據您用來管理 NuGet 相依性的方法,您也可以使用 Visual Studio 直接在 方案總管 或 NuGet 封裝管理員 中檢視相依性。
針對 CLI 環境,您可以使用 dotnet list package
命令 來列出專案或解決方案的相依性。
您也可以使用 dotnet nuget why
命令 來了解為什麼專案未直接參考的可轉移套件(未直接參考的套件)包含在專案的套件圖形中。
如需管理 NuGet 相依性的詳細資訊, 請參閱下列檔。
GitHub 相依性關係圖
📦 套件取用者 | 📦🖊 套件作者
您可以使用 GitHub 的相依性圖表來查看專案相依的套件,以及相依的存放庫。 這可協助您查看其相依性中偵測到的任何弱點。
如需 GitHub 存放庫相依性的詳細資訊, 請參閱下列檔。
相依性版本
📦 套件取用者 | 📦🖊 套件作者
為了確保相依性的安全供應鏈,您會想要確保所有相依性和工具都會定期更新為最新的穩定版本,因為它們通常會包含已知弱點的最新功能和安全性修補程式。 您的相依性可以包含相依的程式碼、您取用的二進位檔、您使用的工具,以及其他元件。 可能包括:
管理相依性
NuGet 已被取代且易受攻擊的相依性
📦 套件取用者 | 📦🖊 套件作者
您可以使用 dotnet CLI 來列出您在專案或解決方案內可能擁有的任何已知已淘汰或易受攻擊的相依性。
您可以使用 命令 dotnet list package --deprecated
或 dotnet list package --vulnerable
提供任何已知淘汰或弱點的清單。
NuGetAudit 可以警告您已知易受攻擊的相依性,而且預設會在來源提供弱點資料庫時啟用。
GitHub 易受攻擊的相依性
📦 套件取用者 | 📦🖊 套件作者
如果您的專案裝載在 GitHub 上,您可以利用 GitHub 安全性 來找出專案中的安全性弱點和錯誤,而 Dependabot 會針對您的程式代碼基底開啟提取要求來修正這些弱點。
在引入弱點之前攔截易受攻擊的相依性是「左移」動作的一個目標。 能夠取得相依性的相關信息,例如其授權、可轉移的相依性,以及相依性的存留期,可協助您執行這項操作。
如需 Dependabot 警示與安全性更新的詳細資訊, 請參閱下列檔。
NuGet 摘要
📦 套件取用者
使用您信任的套件來源。 使用多個公用和私人 NuGet 來源摘要時,可以從任何摘要下載套件。 為了確保您的組建可預測且安全不受相依性混淆等已知攻擊,請瞭解套件來自哪些特定摘要是最佳做法。 您可以使用單一摘要或私人摘要搭配上游功能來保護。
如需保護套件摘要的詳細資訊,請參閱 使用私人套件摘要時降低風險的 3 種方式。
使用私人摘要時,請參閱 管理認證的安全性最佳做法。
用戶端信任原則
📦 套件取用者
有一個原則可讓您選擇加入其中,您需要用來簽署的套件。 這可讓您信任套件作者,只要它是作者簽署,或信任套件是由由 NuGet.org 所簽署之存放庫的特定使用者或帳戶所擁有。
若要設定用戶端信任原則, 請參閱下列檔。
鎖定檔案
📦 套件取用者
鎖定檔案會儲存套件內容的哈希。 如果您想要安裝之套件的內容哈希與鎖定檔案相符,它會確保套件可重複性。
若要啟用鎖定檔案, 請參閱下列檔。
套件來源對應
📦 套件取用者
套件來源對應可讓您集中宣告方案中每個套件應該從 nuget.config 檔案還原的來源。
若要啟用套件來源對應, 請參閱下列檔。
保護計算機
目錄許可權
📦 套件取用者
在 Windows 和 Mac 和某些 Linux 發行版上,用戶帳戶主目錄預設為私人。 不過,某些 Linux 散發套件預設可讓相同電腦上的其他帳戶讀取使用者目錄。 此外,有多個 組態選項可將 NuGet 的全域套件資料夾和 HTTP 快取重新導向至非預設位置。 解決方案、專案和存放庫也可能建立在用戶主目錄之外。
如果您使用任何不在 nuget.org 上的套件,則如果計算機上的任何其他帳戶可以讀取 NuGet 的全域套件或 HTTP 快取目錄,或專案的組建輸出目錄,則這些套件可能會向不應該存取這些套件的人員透露。
在 Linux 上, dotnet nuget update source
將會變更 nuget.config 檔案許可權,使其只能由檔案擁有者讀取。
不過,如果您以任何其他方式編輯 nuget.config 檔案,而且該檔案位於其他帳戶可以讀取檔案的位置,可能會有套件來源 URL 或套件來源認證的相關信息洩漏。
您應該確定同一部計算機的其他用戶無法讀取任何 nuget.config 檔案。
下載目錄中的解決方案
📦 套件取用者
當您在下載目錄中處理解決方案或專案時,應該特別小心。 NuGet 會累積來自多個組態檔的設定,而 MSBuild 通常會從任何父目錄直接匯入 Directory.Build.props、Directory.NuGet.props、Directory.Build.targets,以及其他可能從任何父目錄到文件系統根目錄的檔案。
下載資料夾有額外的風險,因為網頁瀏覽器通常會從因特網下載檔案的預設位置
組建代理程式
📦 套件取用者
建置代理程式 (CI 代理程式)在每次建置之後,都不會重設為初始狀態,因此必須考慮多個風險。
若要瞭解管理認證的安全方式, 請參閱從已驗證摘要取用套件的相關文件。
若要瞭解如何修改 NuGet 儲存資料的目錄,請參閱 管理全域套件、快取和暫存資料夾的檔。 這些目錄應該設定為 CI 代理程式在每個組建之後清除的目錄。
請注意,專案所使用的任何套件都可能留在專案的建置輸出目錄中。 如果您的專案使用來自已驗證來源的套件,則相同 CI 代理程式的其他使用者可能會未經授權存取套件元件。 因此,即使您的組建失敗或取消,您也應該在建置結束時清除存放庫。
監視您的供應鏈
GitHub 祕密掃描
📦🖊 套件作者
GitHub 會掃描 NuGet API 金鑰的存放庫,以防止意外認可的秘密詐騙用途。
若要深入瞭解秘密掃描,請參閱 關於秘密掃描。
撰寫套件簽署
📦🖊 套件作者
作者簽署 可讓套件作者在套件上戳記其身分識別,並讓取用者驗證其來自您身分。 這可保護您免於內容竄改,並做為套件來源和套件真實性的單一事實來源。 結合用戶端信任原則時,您可以確認套件來自特定作者。
若要撰寫簽署套件,請參閱 簽署套件。
可重現的組建
📦🖊 套件作者
可重現的組建會在每次建置時建立位元組對位元組完全相同的二進位檔,並包含原始程式碼連結和編譯程式元數據,讓套件取用者直接重新建立二進位檔,並驗證組建環境尚未遭入侵。
若要深入瞭解可重現的組建,請參閱 使用來源鏈接 產生套件和 可重現的組建驗證 規格。
雙因素驗證 (2FA)
📦🖊 套件作者
nuget.org 上的每個帳戶都已啟用 2FA。 這會增加登入 GitHub 帳戶或 NuGet.org 帳戶時的額外安全性層。
套件識別碼前置詞保留
📦🖊 套件作者
若要保護套件的身分識別,您可以保留套件標識碼前置詞與個別命名空間,以在套件標識碼前置詞適當地落在指定的準則之下,讓相符的擁有者產生關聯。
若要深入瞭解保留標識符前置詞,請參閱 套件標識符前置詞保留。
淘汰和取消列出易受攻擊的套件
📦🖊 套件作者
當您知道您所撰寫套件中的弱點時,若要保護 .NET 套件生態系統,請盡最大努力淘汰並取消列出套件,使其隱藏在搜尋套件的使用者中。 如果您要取用已淘汰且未列出的套件,您應該避免使用套件。
若要瞭解如何淘汰和取消列出套件,請參閱下列有關淘汰和取消列出套件的檔。
也請考慮向 GitHub Advisories Database 報告已知的 。
摘要
您的軟體供應鏈是任何進入或影響程式代碼的專案。 儘管供應鏈妥協是真實的,在受歡迎程度不斷增加,但它們仍然很少見:因此,您可以做的最重要的事情是注意您的 相依性、管理相依性 及 監視供應鏈,以保護您的供應鏈。
您已瞭解 NuGet 和 GitHub 提供的各種方法,可供您立即使用,以更有效地檢視、管理及監視您的供應鏈。
如需保護全球軟體的詳細資訊,請參閱 Octoverse 2020 安全性報告的狀態。