三 十大 CI/CD 安全風險

在上一篇文章,我們了解了依賴鏈濫用和基于流水線的訪問控制不足這兩大安全風險 , 并給出緩解風險的安全建議 。本篇文章將著重介紹 PPE 風險,并提供緩解相關風險的安全建議與實踐 。
Poisoned Pipeline Execution (PPE) 風險指的是攻擊者能夠訪問源代碼控制系統,但無法訪問構建環境,通過將惡意代碼/命令注入構建流水線配置來操縱構建過程,本質上是“中毒的”流水線和運行惡意代碼作為構建過程的一部分 。
風險描述PPE 風險通常存在代碼倉庫中,可控對應的 CI 管道配置文件,通過修改 CI 配置文件達到執行對應命令的目的 。有權操作 CI 配置文件或 CI 流水線任務所依賴的其他文件的攻擊者,可以將惡意命令置入這些文件,通過執行這些惡意命令,最終“毒化”執行這些命令的 CI 流水線 。執行未經審查的代碼的流水線,比如一些直接由拉取請求或提交到任意存儲庫分支觸發的流水線,由于在設計上包含未經任何審查或批準的代碼,更容易受到 PPE 風險的影響 。一旦能夠在 CI 流水線中執行惡意代碼,攻擊者就可以在流水線身份的上下文中進行各種惡意操作 。
PPE 的三種類型直接 PPE(D-PPE)在 D-PPE 場景中,攻擊者修改他們有權訪問的存儲庫中的 CI 配置文件,通過直接將更改推送到存儲庫上未受保護的遠程分支,在提交 PR 時隨著分叉的更改而變化 。由于 CI 流水線執行是由“push”或“PR”事件觸發的,并且流水線執行是由修改后的 CI 配置文件中的命令定義的,一旦構建流水線被攻擊,攻擊者的惡意命令最終會在構建節點中運行觸發 。
間接 PPE(I-PPE)在以下幾種情況下,即便攻擊者能夠訪問 SCM 存儲庫,也無法使用 D-PPE:

  • 流水線配置為從同一存儲庫中單獨的受保護分支中提取 CI 配置文件 。
  • CI 配置文件存儲在與源代碼不同的存儲庫中,則用戶沒有直接編輯它的選項 。
  • CI 構建是在 CI 系統本身中定義的——而不是在存儲在源代碼中的文件中 。
在這幾種情況下,攻擊者就會選擇向流水線配置文件引用的文件中注入惡意代碼來破壞流水線:
  • make:執行“Makefile”文件中定義的命令 。
  • 從流水線配置文件中引用的腳本,與源代碼本身存儲在同一存儲庫中(例如 ,  python myscript.py - myscript.py 將被攻擊者操縱) 。
  • 代碼測試:在構建過程中在應用程序代碼上運行的測試框架依賴于專用文件,這些文件與源代碼本身存儲在同一存儲庫中 。能夠操縱負責測試的代碼的攻擊者能夠在構建中運行惡意命令 。
  • 自動工具:CI 中使用的 Linter 和安全掃描器通常也依賴于存儲庫中的配置文件 。很多時候這些配置涉及從配置文件中定義的位置加載和運行外部代碼 。
因此 , 在 I-PPE 中,不同于將惡意命令直接插入流水線定義文件來破壞流水線,攻擊者通過將惡意代碼注入到配置文件引用的文件中,一旦觸發流水線并運行相關文件中聲明的命令,惡意代碼最終會在流水線節點上執行 。
公共 PPE(3PE)執行 PPE 攻擊需要訪問托管流水線配置文件的存儲庫或其引用的文件 。大多數情況下,只有開發人員擁有此類許可 , 也就是說攻擊者必須要獲得開發工程師對存儲庫的許可和權限才能執行直接或間接 PPE 攻擊 。
然而 , 在一些情況下,互聯網上的匿名攻擊者可以使用“中毒的” CI 流水線:公共存儲庫(例如開源項目)通常允許任何用戶做出貢獻,通過創建拉取請求,建議對代碼進行更改 。這些項目通常使用 CI 解決方案自動測試和構建,與私有項目類似 。如果公共存儲庫的 CI 流水線運行匿名用戶建議的未經審查的代碼,它很容易受到公共 PPE 攻擊,或者簡稱為 3PE 。如果易受攻擊的公共存儲庫的流水線在與私有存儲庫相同的 CI 實例上運行,這也會暴露例如私有項目的敏感信息這類的內部資產 。
PPE 示例通過 D-PPE (GitHub Actions) 竊取憑據在以下示例中,GitHub 存儲庫與 GitHub Actions 工作流程連接,該工作流程獲取代碼、構建代碼、運行測試并最終將工件部署到 AWS 。當新代碼被推送到存儲庫中的遠程分支時,代碼(包括流水線配置文件)由運行程序(工作流節點)獲取 。
name: PIPELINEon: pushjobs: build:runs-on: ubuntu-lateststeps:- run: |echo "building..."echo "testing..."echo "deploying..."
三 十大 CI/CD 安全風險

文章插圖

推薦閱讀