在我們之前的帖子中關於 CI/CD Pipelines, 我們看到 如何破解一個 CI/CD 這種情況 想必 受到保護。
讓我們回顧一下上一篇文章中的觀點: 我們從一些開始 pipeline 那很容易受到 間接中毒 Pipeline 執行 (I-PPE),為了解決這個問題,我們決定將其拆分。 pipeline 分成兩部分:
- 該1st pipeline (建置 CI),符合 D-PPE 和 I-PPE 標準,會檢出 PR 程式碼,進行構建,並產生工件。
- 2nd pipeline (測試 CI),對於 D-PPE 和 I-PPE 也是安全的,可以檢出基礎程式碼(以避免 shell 腳本修改),並針對工件執行原始腳本。
- 為了同步測試 CI pipeline 在建置 CI 之後運行 pipeline, 我們用了 工作流程運行 觸發。
我們將其命名為方案三。
雖然如我們在那篇文章中提到的,還有其他解決方案,但出於教學目的,我們決定實施這個“解決方案”,以便深入探討其脆弱性。 CI/CD pipelines.
之後,我們看到瞭如何透過以下方式破解這種情況: 毒害文物。這就是我們所說的 神器中毒即修改(破解)的能力 pipeline 透過修改邏輯 pipeline 神器。
這種方法有什麼問題?我們看到,當任何用戶「創建」一個新物件時,問題就出現了。 pipeline.
如果使用者開啟一個包含新內容的 PR pipelineGitHub 將執行該操作。 pipeline (在某些條件下,正如我們所看到的) 在文中).
然後用戶就可以建立一個新的 pipeline 與 Build CI 同名!是的,這很令人驚訝,但 GitHub 允許你創建兩個。 pipeline同名的! !
當使用者提交包含這些變更的 PR 時, 新的” pipeline 將被執行(上傳被污染的工件) 以及部署 CI pipeline 之後將執行該腳本,導致「修改後的」shell腳本覆蓋位於以下位置的「原始」shell腳本: pipeline 工作區。因此,這種「解決方案」並不能避免 I-PPE 漏洞(如下圖)。
問題是什麼?至少存在以下幾個問題:
- 首先, 如何確保建置過程沒有被竄改? 在這種情況下,惡意使用者能夠利用其權限修改預期的建置流程。 pipeline 製造一件有毒的物品。
- 其次, 如何判斷一件文物的來源?
這些問題將我們拋入…的懷抱 軟體認證 領域! !
軟體認證
An 證明 是一塊 數據 代表 事件證明在現實世界中,我們通常稱這些為 認證.
例如,當實驗室進行血液檢測時,檢測數據會被記錄並認證。血液檢測結果就是如此。 可驗證 以及 可追溯的.
更貼近我們的 IT 領域,你可以猜到這個過程如果翻譯成例如編譯過程會是什麼樣子。
此類證明將包含有關編譯伺服器環境和工具、材料(原始碼)以及產品/工件(二進位程式碼)的資訊。
顯然,為了確保可信度,證明文件必須由經授權的證明人(經過認證且不可否認)出具。
可能你們中的一些人會想…那什麼是… 簽名與證明的區別?
代碼簽名和證明
從高層次來看, 一步對社區作出貢獻,最終決定推出別具意義 它是使用密鑰對和工件創建的。密鑰對由公鑰和私鑰組成。
使用者使用私鑰對工件進行簽名,其他人可以使用公鑰驗證簽名。私鑰必須保密,公鑰則廣泛分發。
簽名可以用於 為了證明私鑰持有者使用私鑰對文物進行了簽署。.
簽名 不要證明
- 用戶的 意圖 在文物上簽名(他們可能被騙了),或者
- 用戶意圖進行任何 關於該文物的具體說法
與 證明書使用者不是直接對工件進行簽名,而是創建某種形式的簽名。 文件 每 捕捉到他們的意圖 在簽署文物之後以及任何 具體訴求 這是作為此簽名的一部分而做出的。
整體證明框架
最常見的框架是 整體證明框架
- 定義一個 standard 證明文件的格式 將主題(即被描述的製品)與關於該製品的已認證元資料綁定在一起。
- 提供了一套 預定義謂詞 用於在整個軟體供應鏈中以及跨軟體供應鏈傳遞經過認證的元數據
讓我們詳細了解一下證明文件的格式。
An 證明書 數位簽名文件 包含 聲明。
这 聲明 是證明文件的中間層,將其與特定文件綁定。 主題 並明確識別出以下類型: 謂詞:
- 主題:“ 對該物品進行加密安全的引用 (通常透過哈希值),以及
- 謂詞一組特定的 索賠 關於該工件的描述被稱為聲明。這些聲明可以用來表達(並在之後證明)你能想到的任何事情!它們可以代表人工審批、工件來源、自動化測試結果、稽核追蹤等等!
當該聲明經過加密簽署後,它就被稱為一份聲明。 證明書
這樣,例如,Alice 創建了一個關於某個物品的聲明,並使用她的私鑰對其進行簽名,從而創建了一個證明。
- 鮑伯就可以 驗證簽名 在那份證明中,允許他 相信這些說法 內。
然後,鮑伯就可以利用這些主張了。 決定 是否允許使用此文物。
認證能否協助解決文物中毒問題?
在對證明進行了以上介紹之後,讓我們回到我們的問題。 證明如何幫助我們解決問題,即避免人工製品污染?
惡意使用者能夠繞過「官方」機制來創建工件,即透過使用他/她自己的… pipeline 產生該工件。
如果我們能夠證明下載的這些工件是用官方版本建構的,那就太棒了。 pipeline這只是我們可以稱之為「篡改點」的一個例子,但可能還有很多其他的篡改點。
如上圖所示,篡改點不只一個。這樣,消費者 pipeline (本例為測試 CI)必須評估 建置過程的完整性 以及 文物本身的完整性.
在我們的例子中,被污染的人工製品是透過引入一個新的(被污染的)人工製品而創造出來的。 pipeline 這會篡改建置過程。但惡意使用者可能還能夠:
- 從程式碼庫檢出後修改程式碼。 SCM 產生惡意二進位文件
- 將編譯產生的正確二進位檔案替換為任何其他惡意二進位檔案。
- 破壞工件註冊表並上傳以任何其他方式建置的惡意工件
- 等。
如您所見,可能存在多個「篡改」點。
這裡最重要的是什麼?顯然是保護所有那些「篡改」點。但歸根究底,最重要的是 也就是說,產品的「消費者」可以評估產品的完整性,並決定是否繼續使用該產品。
我們可以 評估文物的完整性 有兩種方式。
一種方法是透過評估 出處 該文物。
透過生成 出處證明我們提供關於該工件的有用元資料(經過適當認證且不可否認)。 在以下範例中,我們將使用 Xygeni SALT (Software Attestations Layer for Trust),用於產生、註冊和驗證軟體證明的元件。
- name: Building ... run: | # mvn will compile and create target/MyApp.war mvn clean package - name: Generating provenance run: | #!/usr/bin/env bash shopt -s expand_aliases alias salt=$PWD/salt_pro/xygeni_salt/salt echo " " echo "-----------" echo "Generating Provenance with CLI ..." salt at slsa \ --basedir ${GITHUB_WORKSPACE}/target \ --key="${PRIVATE_KEY}" \ --public-key=${GITHUB_WORKSPACE}/Test1_public.pem \ --key-password=${KEY_PASSWD} \ --output-unsigned=${GITHUB_WORKSPACE}/cli_provenance_${PIPELINE}_unsigned.json \ --pipeline ${PIPELINE} --pretty-print \ --file ./MyApp.war 在上面的程式碼中,你可以看到第一個步驟是建立 war 文件,第二個步驟是產生 war 檔。 出處證明為了做到這一點, pipeline 使用私鑰,證明中也包含了公鑰。
幕後,Xygeni 的 鹽 該命令將證明存儲在 總帳 (又稱證明登記處, 記錄 在我們的例子中是這樣,但您可以使用任何其他方法)。 完成這些之後,消費者 pipeline 可以包含 Xygeni 的 驗證引擎 驗證文物的來源並評估文物的完整性。
- name: 'Verifying the attestation' run: | #!/usr/bin/bash echo " " echo "-------" # Calculate sha256sum for the artifact SHA_SUM=$(sha256sum ./MyApp.war | cut -f1 -d ' ') # Recover the attestation Id from the sha256sum ATT_ID=$(echo $(salt -q registry search --digest sha256:$SHA_SUM --format json) | jq -r .[-1].gitoidSha256) echo " " echo "-------" # Download the provenance attestation echo "Downloading the provenance attestation ..." salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json echo " " echo "-------" echo "Verifying provenance ..." salt verify \ --basedir ${GITHUB_WORKSPACE} \ --attestation=${GITHUB_WORKSPACE}/provenance_kk.signed.json \ --public-key=${GITHUB_WORKSPACE}/Test1_public.pem \ --file ./MyApp.war 驗證過程評估以下內容:
- 这 工件 sha256sum 有效 (即,存在關於該「主題」的證明文件),
- 这 證明文件已妥善認證 (它是使用相應的私鑰生成的)
此驗證過程可以評估工件和證明文件是否有效。
但是,正如你所記得的,在我們的案例中,該工件是由「惡意」程式產生的。 pipeline (即並非原版,而是修改版) pipeline那我們必須繼續檢查另一個方面: 該文物由「原件」產生。 pipeline不是其他任何一種。
為此,只需添加一行簡單的程式碼來檢查該條件,例如:
echo " " echo "-------" # Download the provenance attestation echo "Downloading the provenance attestation ..." salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json WFR=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json |base64 -d | jq -r .predicate.buildDefinition.internalParameters.environment.GITHUB_WORKFLOW_REF) echo $WFR | grep cicd_top10_3_salt\/.github\/workflows\/build.yml 如果該工件並非由我們的「安全性」環境生成,則此附加檢查將失敗。 pipeline.
如果文物是由我們最初的…生成的 pipeline (cicd_top10_3_salt/.github/workflows/build.yml),grep 指令將成功執行,否則將失敗,導致程式崩潰。 pipeline 併中止所有後續步驟。
“建造者” pipeline 這只是需要檢查的篡改點之一,但正如前面提到的,還有其他一些篡改點需要檢查。
例如, 如果在程式碼庫檢出之後、建置指令執行之前,原始碼被竄改了怎麼辦? 在這種情況下,要建置的程式碼與儲存在…中的程式碼不同。 SCM.
檢查這個篡改點非常簡單,只需檢查每一步材料的雜湊值即可。
SHA_ATT_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[0].predicate.materials[].digest[]) SHA_STEP_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[3].predicate.materials[0].digest[]) 結論
總之, 軟體認證 是對一段軟體所做的斷言,即關於軟體製品或軟體製品集合的經過驗證的聲明(元資料)。
軟體認證是對原始工件/程式碼簽署的一種概括。認證是一份已簽署的文件(採用特定格式,通常基於 JSON),它將元資料與工件關聯起來。它們代表了每個建置步驟中輸入(材料)和輸出(產生的工件)之間的關聯證據。
證明文件提供了建構最終軟體工件所執行步驟的可驗證記錄,包括每個步驟的輸入材料和運行的建置命令。
總之,軟體認證是檢視我們建置過程中許多不同完整性方面的絕佳機制。
看完這部劇了嗎?別擔心!隨時可以跳回“中毒 Pipeline 執行(PPE)或任何其他再次引起你興趣的帖子!
敬請期待,我們將深入探討軟體認證和 build security 在後續的部落格文章中。




