GitHub主要倉庫泄露訪問令牌,代碼與云環(huán)境面臨風(fēng)險
對一些大型公司的開源庫中GitHub Actions工作流生成的構(gòu)建工件進行的分析顯示,這些工件中包含了對第三方云服務(wù)以及GitHub本身的敏感訪問令牌,此外,GitHub在今年對工件功能進行的一項改動引入了一種競爭條件,攻擊者可以利用這一點來濫用此前無法使用的GitHub令牌。
Palo Alto Networks的研究員Yaron Avital進行的調(diào)查發(fā)現(xiàn),在數(shù)十個公共庫中存儲的工件中發(fā)現(xiàn)了機密信息,其中一些庫對應(yīng)的項目由Google、Microsoft、Amazon AWS、Canonical、Red Hat、OWASP等大型組織維護,這些令牌提供了對各種云服務(wù)和基礎(chǔ)設(shè)施、音樂流媒體服務(wù)等的訪問權(quán)限。
“這使得惡意行為者能夠通過訪問這些工件,潛在地破壞這些機密信息所授予訪問權(quán)限的服務(wù),”Avital在報告中寫道,“在我們此次研究中發(fā)現(xiàn)的大多數(shù)易受攻擊的項目中,最常見的泄露是GitHub令牌的泄露,這使得攻擊者能夠?qū)τ|發(fā)的GitHub庫采取行動,這可能導(dǎo)致惡意代碼的推送,通過CI/CD管道流入生產(chǎn)環(huán)境,或訪問存儲在GitHub庫和組織中的機密信息?!?/p>
機密信息如何被包含在工件中
GitHub Actions是一種CI/CD服務(wù),允許用戶在GitHub或自己的基礎(chǔ)設(shè)施中設(shè)置工作流,以自動化代碼構(gòu)建和測試,這些工作流在.yml文件中使用YAML語法定義,當(dāng)庫中發(fā)生特定觸發(fā)器或事件時會自動執(zhí)行。例如,新代碼提交可能會觸發(fā)一個操作來編譯和測試該代碼并生成報告。
Actions工作流通常會生成構(gòu)建工件,這些工件可以是編譯后的二進制文件、測試報告、日志或其他執(zhí)行工作流及其各個作業(yè)所產(chǎn)生的文件,這些工件會被存儲90天,并且可以被其他工作流或同一工作流的一部分所使用。在開源項目中,這些工件通常對所有人可見
然而,在工作流執(zhí)行過程中,常常會將訪問令牌臨時存儲在容器的環(huán)境變量或其他臨時文件中,以便作業(yè)能夠訪問完成所需的外部工具和服務(wù)。因此,必須格外小心,確保這些機密信息在工作流完成后不會離開該環(huán)境。
Avital發(fā)現(xiàn)的一個示例是,一個被許多項目使用的流行代碼靜態(tài)檢查工具生成了一個日志,該日志包括了環(huán)境變量;該日志隨后被保存為一個工件。代碼靜態(tài)檢查工具是靜態(tài)代碼分析工具,用于查找錯誤、漏洞和風(fēng)格問題,以提高代碼質(zhì)量。
更常見的是,通過使用actions/checkout命令創(chuàng)建庫的本地克隆,以執(zhí)行作業(yè)時暴露了GitHub令牌。作為這一過程的一部分,會創(chuàng)建一個臨時的GITHUB_TOKEN并將其保存到本地.git文件夾中,以允許執(zhí)行經(jīng)過認證的git命令,該令牌應(yīng)為臨時令牌,并在工作流完成后停止工作,但如果暴露,仍然有方法可以濫用它。
“根據(jù)我的觀察,用戶通常——也是錯誤地——將他們整個checkout目錄作為工件上傳,”Avital在他的報告中寫道,“該目錄包含存儲持久化GITHUB_TOKEN的隱藏.git文件夾,導(dǎo)致公開可訪問的工件中包含了GITHUB_TOKEN。”
Avital在工件中發(fā)現(xiàn)的另一個GitHub令牌是ACTIONS_RUNTIME_TOKEN,它在調(diào)用特定的GitHub Actions時存儲在環(huán)境變量中,例如actions/cache和actions/upload-artifact。與僅在工作流運行期間有效的GITHUB_TOKEN不同,ACTIONS_RUNTIME_TOKEN即使在工作流完成后仍然有效六小時,因此存在較大的濫用風(fēng)險。
“我自動化了一個流程,可以下載工件,提取ACTIONS_RUNTIME_TOKEN,并使用它來替換該工件為惡意版本,”這位研究人員寫道,“后續(xù)的工作流作業(yè)通常依賴于之前上傳的工件,這類情況為遠程代碼執(zhí)行(RCE)打開了大門,攻擊者可以在運行作業(yè)的Runner上執(zhí)行惡意工件。如果開發(fā)人員下載并執(zhí)行了惡意工件,也可能導(dǎo)致工作站被入侵?!?/p>
新的GITHUB_TOKEN競態(tài)條件
如前所述,GITHUB_TOKEN在工作流完成時失效,工件只有在工作流完成后才可用,然而,自今年二月起,情況發(fā)生了變化。
GitHub Actions Artifacts的第4版引入了在工作流運行期間通過用戶界面或API下載工件的功能,這是社區(qū)請求的一項功能,在許多情況下非常有用,例如在批準發(fā)布前審查工件,或在有許多作業(yè)的工作流中盡早獲取工件,以節(jié)省完成所有作業(yè)所需的時間。
但隨著Avital發(fā)現(xiàn)GITHUB_TOKEN經(jīng)常在工件中暴露,這一新功能也引入了一個攻擊者可能利用的競態(tài)條件:如果攻擊者知道工作流何時開始,他們可以嘗試在工作流尚未完成時獲取工件并提取GITHUB_TOKEN,因為此時該令牌仍然有效。
成功率因工作流而異。在許多情況下,生成工件是作業(yè)執(zhí)行的最后一步之一,因此下載工件、提取令牌并進行惡意操作的時間窗口非常小,然而,一些工作流在生成工件后還有更多步驟,因此只需找到這些工作流即可。正如Avital指出的那樣,已經(jīng)切換到v4版本工件API的項目列表正在迅速增長,因為v3版本計劃在11月棄用。
為了擴大攻擊范圍和可以針對的工作流數(shù)量,這位研究人員通過創(chuàng)建一個惡意工作流顯著提高了攻擊的性能。該惡意工作流運行在GitHub的基礎(chǔ)設(shè)施上,并在目標庫中的某個工作流執(zhí)行時觸發(fā)。惡意工作流每秒發(fā)送數(shù)十個API請求,以便立即檢測到工件生成并下載它。雖然工件是歸檔的,但研究人員創(chuàng)建了一個腳本,只提取包含令牌的git配置文件,而不是解壓整個工件,從而顯著提高了攻擊的效率。
緩解措施
為了幫助防御此類攻擊,這位研究人員創(chuàng)建了一個名為upload-secure-artifact的自定義GitHub操作,其他人可以將其包含在他們的工作流中,以掃描生成的工件中的機密信息,并在檢測到任何機密信息時阻止其上傳。
“GitHub棄用Artifacts V3應(yīng)該促使使用該工件機制的組織重新評估他們的使用方式,”研究人員寫道,“根據(jù)最小權(quán)限原則減少runner令牌的工作流權(quán)限,并審查CI/CD管道中的工件創(chuàng)建過程?!?/p>