
AsyncAPI 可信 provenance 照出毒包:GitHub Actions 個窿點樣放行
五個惡意版本經官方發布鏈上架,開發團隊要追查舊 cache 同 CI
7 月 14 日,四個 @asyncapi 套件俾人塞入惡意程式,再經 AsyncAPI 自己嘅發布鏈送上 npm。三星期後值得再睇,重點已經唔只係「邊個版本有毒」:AsyncAPI 公布嘅調查解釋咗,一個已有人提出修補、但仍未 merge 嘅 GitHub Actions 問題,點樣一路升級成跨 repo 供應鏈事故。iThome 報道亦歸納咗四個環環相扣嘅弱點,包括危險嘅 pull_request_target 用法、權限過闊嘅 bot 憑證、欠缺人手關卡嘅 OIDC 發布,同攻擊者用大量 PR 掩住行蹤。
一個 PR 攞走成個組織嘅鎖匙
出事嘅 workflow 用 pull_request_target 接收外來 PR,同時 checkout、執行 fork 入面由投稿者控制嘅程式。呢類 job 喺主 repo 權限環境運行,惡意程式最終攞到 asyncapi-bot 憑證。偏偏呢個 bot 有跨 repo 管理權,分支規則亦冇約束管理員,攻擊者於是可以 force-push 去發布分支,再由 asyncapi/generator 橫向走入 asyncapi/spec-json-schemas。期間佢仲大量開垃圾 PR,再逐一關返,塞滿通知同 CI 紀錄,令維護者更難追查。

圖片:AsyncAPI
Provenance 有效,套件一樣可以有毒
攻擊者冇偽造 npm 身分,亦冇直接偷 npm 發布 token。惡意 commit 真係由 AsyncAPI repo 嘅合法 workflow 經 OIDC Trusted Publishing 發布,所以五個版本照樣有有效 provenance。呢個標記證明套件由邊個 workflow、commit 同 ref 產生,唔會替你判斷嗰段原始碼安唔安全。當 repo、分支權限同發布關卡已經失守,provenance 只會如實證明「官方條生產線造咗呢件貨」。
五個版本要逐個查,舊 cache 都唔好漏
AsyncAPI 官方列出嘅惡意版本係 @asyncapi/[email protected]、@asyncapi/[email protected]、@asyncapi/[email protected]、@asyncapi/[email protected] 同 6.11.2-alpha.1。事故報告列出嘅 last safe 版本分別係 3.3.0、1.1.0、0.7.0 同 6.11.1;受影響團隊應鎖定呢啲版本,或者揀經重新核實嘅較新乾淨版本。五個惡意版本已從 npm 清走,但「registry 冇咗」唔等於公司內部副本一齊消失。
先搜 package-lock.json、npm-shrinkwrap.json、yarn.lock、pnpm-lock.yaml 同 SBOM,直接依賴同間接依賴都要計。跟住查 npm、pnpm 或 Yarn cache、保存落嚟嘅 node_modules、Docker image、CI cache、build artifact 同 7 月 14 日前後嘅 job 紀錄。lockfile 有惡意版本只證明系統曾經解出嗰個版本;要判斷有冇執行,仲要對照 build、測試、文件產生器或 app 有冇載入相關 module。
點解 --ignore-scripts 完全擋唔住
今次 payload 冇靠 preinstall、postinstall 呢類 lifecycle script。JFrog 同其他研究團隊分析指,惡意碼收埋喺正常程式檔,去到 Node.js require() 或 import 套件嗰刻先啟動,開一個分離嘅 Node process,再從 IPFS 拉第二階段程式。即使安裝時落咗 npm install --ignore-scripts,之後 build、測試或產生文件一載入套件,惡意碼仍然照跑。研究人員對佢同既有 Miasma 行動嘅直接關係有唔同判斷;AsyncAPI 為免混淆,喺報告叫呢個 payload 做 M-RED-TEAM。
中招後唔好淨係刪套件
曾經載入惡意版本嘅開發機或 runner,應先當成可能失守,隔離部機再處理,再由乾淨裝置撤銷同輪替當時可讀到嘅 GitHub、npm、雲端、SSH、簽署同部署憑證。重建 runner、容器同 artifact,亦要翻查異常 Node process、對外連線,同埋 Windows %LOCALAPPDATA%\NodeJS\sync.js、macOS ~/Library/Application Support/NodeJS/sync.js、Linux ~/.local/share/NodeJS/sync.js 呢啲官方列出嘅痕跡。清 cache、重裝依賴或者換一個 token,各自都只處理部分風險,唔足以單獨證明環境乾淨。
自家 GitHub Actions 要查邊幾處
開發團隊而家最實際係掃一次 .github/workflows:搵出所有 pull_request_target,睇佢哋有冇 checkout PR head、安裝外來依賴或執行投稿者程式;再逐個檢查 permissions、PAT、service account、repo secret 同 GITHUB_TOKEN 權限。發布帳戶唔應該持有全組織管理權,branch rules 要套用到管理員同 bot,release job亦應加入 environment approval 或 npm staged publishing。OIDC 仍然值得用,但自動發布前欠咗獨立審批,今次同類情況仍然可以再發生。
參考來源
- iThome — AsyncAPI開發團隊承認是未處理的GitHub Actions配置不當問題引發供應鏈攻擊 — original report
- AsyncAPI:Miasma Supply Chain Attack Incident Report — 官方事故報告,核對攻擊時間線、受影響版本、根因、清理進度同主機痕跡。
- OSV:Malicious code in @asyncapi/generator — 核對 generator 3.3.1 惡意版本、最後安全版本同惡意 commit。
- OSV:Malicious code in @asyncapi/specs — 核對 specs 6.11.2 同 6.11.2-alpha.1 紀錄。
- JFrog Security Research:Miasma Worm Returns to npm — 獨立拆解 module 載入時啟動嘅 payload、執行條件同有效功能。
- GitHub Docs:Secure use reference — GitHub 官方列明
pull_request_target配合外來程式碼嘅安全風險。 - npm Docs:Trusted publishing for npm packages — 核對 OIDC Trusted Publishing、provenance、自動發布同 staged publishing 機制。
本文根據原文及公開資料整理;資料有出入時,以原文及官方資料為準。







