後端工坊 2026 年 9 月 22 日

2026-09-22 — Miri快取寫入全部環境變數導致CI洩密事件

primary=https://blog.rust-lang.org/2026/09/21/github-actions-leaking-secrets-when-miri-output-is-cached/ primary=https://github.com/rust-lang/miri/pull/5337

Miri快取寫入全部環境變數導致CI洩密事件

Rust官方部落格 · 2026-09-21

問題出在cargo miri建置時會把整組環境變數原封不動寫進target/目錄,用來讓稍後的執行期環境與建置期保持一致。Rust安全團隊在官方部落格指出,這個機制不分青紅皂白保留了所有變數,其中包含帶有token與密鑰的敏感內容,而不只是建置真正需要的少數幾筆。這批殘留資料一旦被外部快取保留下來,就成了外洩的破口。

漏洞機制

多數Rust專案的CI會用actions/cacheswatinem/rust-cache把整個target/目錄存起來,跨不同的workflow run重複使用以加速建置。關鍵在於存取權限的落差:main分支跑完CI後寫入的快取,之後由pull request觸發的CI卻擁有讀取權限。只要有人對repo開一個PR並觸發CI,就能把快取裡殘留的環境變數整批讀出來,裡頭可能藏著先前main分支CI使用過的密鑰。

更麻煩的是這種攻擊難以事後追查。原文提到,攻擊者可以先觸發CI擷取快取內容,再用後續commit覆蓋掉痕跡;GitHub介面有時會隱藏被覆蓋的commit,加上執行紀錄本身數個月後就會被刪除,事後稽核幾乎無從查起。

受影響範圍

Rust安全團隊表示已確認一個repository實際存在可被利用的洩密狀況,另外還找到七個repository具備相同的高風險組合:用cache保留target/、同時對PR開放讀取、且CI中會執行cargo miri,但尚未證實已被利用。團隊已聯繫相關維護者處理。

原文特別點名:凡是在GitHub Actions上用類似快取模式跑Miri或其他工具鏈的Rust專案,都該視為潛在受影響對象,需要檢查自己的cache範圍設定、確認main分支寫入的快取是否對PR開放讀取、並盤點CI步驟裡是否曾把密鑰暴露給會被快取的目錄。

修補與緩解

短期修補是PR #5337,由RalfJung合併進master。修改後的cargo-miri/src/util.rs不再保留全部環境變數,只留下cargo真正會變動、且非token類的CARGO_*變數,以及OUT_DIR,其餘一律過濾掉。這個修補已收進2026-09-22的nightly版本。

// 修補前:cargo-miri/src/util.rs 保留整組環境變數
for (key, value) in std::env::vars() {
    preserved_env.insert(key, value);
}

// 修補後(PR #5337):只留 cargo 真正變動過、非 token 的變數
for (key, value) in std::env::vars() {
    if key.starts_with("CARGO_") && !key.ends_with("_TOKEN") {
        preserved_env.insert(key, value);
    }
}
preserved_env.insert("OUT_DIR".into(), out_dir);

原文建議受影響專案立即採取三個動作:停用會跑Miri那些job的快取、把密鑰限縮在非Miri步驟才能讀到、或暫時關掉Miri直到升級完成。同時應該清掉既有的快取內容,並將可能已外洩的密鑰全部輪替,因為快取一旦寫入過,光是升級Miri版本並不會清除舊有的殘留資料。

原始來源:Rust Blog: GitHub Actions leaking secrets when Miri output is cached


End of article
0
Would love your thoughts, please comment.x
()
x