保護軟體供應鏈的最佳做法

開放原始碼無處不在。 它位於許多專屬的程式代碼基底和社群專案中。 對於組織和個人來說,今天的問題不在於您是否使用開源代碼,而是在於您使用了哪些開源代碼,以及使用量是多少。

如果您不了解軟體供應鏈的詳細資訊,其中一個依賴項中的上游的安全漏洞可能是致命的,使您和您的客戶容易受到潛在危害。 在本檔中,我們將深入探討「軟體供應鏈」一詞的意義、為何重要,以及如何使用最佳做法協助保護您的項目供應鏈。

Octoverse 2020 開放原始碼現況

相依性

軟體供應鏈一詞是用來表示構成您軟體的所有元素,以及其來源。 軟體供應鏈依賴的是它的相依性及這些相依性的屬性。 相依性是軟體執行所需的專案。 它可以是程式代碼、二進制檔或其他元件,以及它們的來源,例如存放庫或套件管理員。

其中包含撰寫程式代碼的人員、程式代碼被提交的時間、如何檢閱其安全性問題、已知的弱點、支援的版本、授權資訊,以及在流程中任意時間點觸及它的所有內容。

您的供應鏈也包含堆疊以外的其他部分,例如您的組建和封裝腳本,或執行應用程式所依賴基礎結構的軟體。

弱點

目前,軟體相依性十分普遍。 您的專案通常會針對您不需要自行撰寫的功能使用數百個開放原始碼相依性。 這可能表示您的應用程式大部分是由您未撰寫的程式代碼所組成。

The State of the Octoverse 2020 - DependenciesOctoverse 2020 - 相依性

第三方或開放原始碼相依性的可能弱點可能是您無法像您所撰寫的程式代碼一樣嚴格控制相依性,這可能會在您的供應鏈中產生潛在的安全性風險。

如果其中一個相依性有弱點,您也有弱點。 這可能是可怕的,因為您的其中一個相依性可能會變更,而您甚至不知道。 即使弱點目前存在於相依性中,但無法利用,未來仍可加以利用。

能夠利用數千個開放原始碼開發人員和連結庫作者的工作,表示成千上萬的陌生人可以有效地為您的生產程序代碼做出貢獻。 透過軟體供應鏈,您的產品會受到未修補的弱點、無辜的錯誤,甚至是針對相依性的惡意攻擊所影響。

供應鏈漏洞

供應鏈的傳統定義來自製造:這是製作和提供東西所需的程序鏈結。 它包括規劃、材料供應、製造和零售。 軟體供應鏈類似,除了材料之外,它是程序代碼。 不是製造,而是開發。 程序代碼不是從地面挖掘礦石,而是從供應商、商業或 開放原始碼 來源,一般而言,開放原始碼程式代碼來自存放庫。 從存放庫新增程式代碼表示您的產品相依於該程序代碼。

當惡意代碼故意新增至相依性時,就會發生軟體供應鏈攻擊的一個範例,使用該相依性供應鏈將程式碼散發給受害者。 供應鏈攻擊是真實的。 有許多方法可以攻擊供應鏈,包括直接作為新的貢獻者插入惡意代碼、在不被他人察覺的情況下接管參與者的帳戶,甚至破壞簽署密鑰來散發不屬於官方相依性套件的軟體。

軟體供應鏈攻擊本身很少是最終目標,而是攻擊者插入惡意代碼或為未來存取提供後門的機會的開始。

Octoverse 2020 - 漏洞生命周期現狀

未修補的軟體

今天使用 開放原始碼 很重要,預計不會很快放緩。 假設我們不會停止使用開放原始碼軟體,供應鏈安全性的威脅是未修補的軟體。 知道這一點,如何解決專案相依性有弱點的風險?

  • 了解您的環境之中的事物。 這需要探索您的相依性和任何可轉移的相依性,以了解這些相依性的風險,例如弱點或授權限制。
  • 管理您的依賴項。 探索到新的安全性弱點時,您必須判斷是否受到影響,如果是的話,請更新為最新版本和安全性修補程式。 這尤其重要,需檢閱引進新相依性的變更或定期稽核較舊的相依性。
  • 監視您的供應鏈。 透過稽核您已經實施的控制措施來管理相依性。 這可協助您針對依賴項目強制執行更具限制的條件。

Octoverse 2020 - 公告

我們將涵蓋 NuGet 和 GitHub 提供的各種工具和技術,您目前可以使用這些工具和技術來解決專案內的潛在風險。

瞭解您的環境中的內容

具有已知弱點的套件

📦 套件取用者 | 📦🖊 套件作者

.NET 8 和 Visual Studio 17.8 新增了 NuGetAudit,可在還原期間針對具有已知漏洞的直接套件發出警告。 .NET 9 和 Visual Studio 17.12 已變更預設設定,以警告有關傳遞性套件的問題。

NuGetAudit 需要來源來提供已知的漏洞資料庫,因此如果您未使用 nuget.org 作為套件來源,您應該將其新增為 稽核來源

當 NuGet 向您發出警告時,該弱點已經是公眾所知的。 攻擊者可以使用此公開洩漏來針對尚未修補其應用程式的目標開發攻擊。 因此,當您收到專案正在使用的套件有已知弱點的警告時,您應該快速採取動作。

NuGet 相依性圖表

📦 套件取用者

您可以直接查看個別項目檔,以檢視專案中的 NuGet 相依性。

這通常位於兩個位置的其中一個:

根據您用來管理 NuGet 相依性的方式,您也可以使用 Visual Studio 在方案總管或 NuGet 套件管理員中直接檢視相依性。

針對 CLI 環境,您可以使用 命令來列出專案或解決方案的相依性。 您也可以使用 `dotnet nuget why` 命令來了解為什麼專案未直接參考的傳遞性套件會包含在專案的套件圖形中。

如需管理 NuGet 相依性的詳細資訊,請參閱以下文件

GitHub 相依性關係圖

📦 套件取用者 | 套件作者

您可以使用 GitHub 的相依性圖表來查看專案相依的套件,以及相依的存放庫。 這可協助您查看其相依性中偵測到的任何弱點。

如需 GitHub 存放庫相依性的詳細資訊,請參閱下列說明文件。

相依性版本

套件使用者 | 套件作者

為了確保相依性的安全供應鏈,您會想要確保所有相依性和工具都會定期更新為最新的穩定版本,因為它們通常會包含已知弱點的最新功能和安全性修補程式。 您的相依性可以包含相依的程式碼、您取用的二進位檔、您使用的工具,以及其他元件。 可能包括:

管理相依性

NuGet 已棄用且存在安全漏洞的應用程式相依性

📦 套件取用者 | 📦🖊 套件作者

您可以使用 dotnet CLI 來列出您的專案或方案中任何已知已棄用或有漏洞的依賴項。 您可以使用命令 dotnet list package --deprecateddotnet list package --vulnerable 來獲取任何已知不推薦使用項或漏洞的清單。 NuGetAudit 可以警告您已知有漏洞的相依性,當 來源提供弱點資料庫時會自動啟用

GitHub 易受攻擊的相依性

📦 套件取用者 | 套件作者

如果您的專案託管在 GitHub 上,您可以利用 GitHub 安全性來找出專案中的安全性弱點和錯誤,而 Dependabot 會自動針對您的程式碼庫開啟合併請求來修正這些弱點。

在引入弱點之前預防易受攻擊的相依性是「Shift Left」概念的一個目標。 能夠取得相依性的相關信息,例如其授權、可轉移的相依性,以及相依性的存留期,可協助您執行這項操作。

如需 Dependabot 警示與安全性更新的詳細資訊,請參閱以下文件。

NuGet 配置

📦 套件使用者

在專案存放庫的根目錄中新增nuget.config檔案。 這被視為最佳做法,因為它會提升可重複性,並確保不同的使用者具有相同的 NuGet 設定。 建議您新增 clear 元素,以確保不會套用任何使用者或計算機特定的設定。 深入瞭解如何套用設定

例如:

<configuration>
  <packageSources>
    <clear />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
  <packageSourceMapping>
    <clear />
  </packageSourceMapping>
</configuration>

小提示

如果您的組織封鎖了對 api.nuget.org的存取,可以請網路管理員https://data.nuget.org/v3/index.json允許並設定為 NuGet Audit稽核來源。 這個端點只提供漏洞資料,不提供套件,因此即使 api.nuget.org 被封鎖,也可能被允許。

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 帳戶時增加一層額外的安全性。

套件識別碼前置詞保留

📦🖊 套件作者

若要保護套件的身分識別,您可以保留具有相應命名空間的套件 ID 前綴,若套件 ID 前綴適當地符合指定的準則,則可將相符的擁有者關聯起來。

若要深入了解保留 ID 前辍,請參閱套件 ID 前辍保留

淘汰和取消列出易受攻擊的套件

📦🖊套件作者

當您知道您所撰寫套件中的弱點時,為了保護 .NET 套件生態系統,請盡最大努力將套件標示為不建議使用並取消列出,以避免出現在搜尋套件的使用者前。 如果您要取用已淘汰且未列出的套件,您應該避免使用套件。

若要瞭解如何停止使用和隱藏套件,請參閱下列有關 停止使用 和 隱藏套件 的文件。

也請考慮向 GitHub 建議資料庫報告已知的問題。

摘要

您的軟體供應鏈是任何進入或影響程式代碼的元素。 儘管供應鏈漏洞是真實存在且數量日益增多,但它們仍然很少見;因此,您可以做的最重要的事情是關注您的依賴關係、管理依賴關係及監控供應鏈,從而保護您的供應鏈。

您已瞭解 NuGet 和 GitHub 提供的各種方法,幫助您在當前更有效地檢視、管理及監控您的供應鏈。

如需瞭解如何保護全球軟體的更多資訊,請參閱《2020 年 Octoverse 安全性報告》。