每週1億次下載的axios被投毒了,但是原始碼裡沒有一行惡意程式碼!

今天上午,有個哥們在群裡發了一句話:

"axios 被投毒了。"

我第一反應是不可能。axios 每週 1 億次下載,npm 上 Top 10 的套件,誰敢動它?

然後我去翻了 GitHub issue,翻了安全公司的分析報告。越看越不對勁。

axios 的 GitHub 倉庫裡,一行惡意程式碼都沒有。你盯著原始碼看一萬遍,什麼都發現不了。

問題根本不在原始碼裡。


到底發生了什麼

有人偷了 axios 維護者的 npm 帳號,繞過 GitHub,直接往 npm registry 發了兩個「官方版本」。

axios 程式碼本身沒改。只是在 package.json 的相依裡加了一個你從沒見過的套件:plain-crypto-js。

你 npm install 的瞬間,這個包的 postinstall 腳本自動跑起來:檢測作業系統,下載遠端控制木馬(RAT),連上攻擊者伺服器。然後自我刪除,把 package.json 替換成乾淨版本。

你事後翻 node_modules,什麼痕跡都沒有。

就好像你去五金行買了一把鎖,品牌對、包裝對、外觀對,但裡面被人換成了帶後門的。你裝上了,用著正常,別人隨時能開你家門。一般漏洞是鎖有缺陷,換一把就行。這次是鎖在到你手裡之前就被掉包了。


攻擊時間線

我把時間線拉出來:

T-18 小時:攻擊者用一次性帳號發佈了 [email protected]。

注意,這個版本是乾淨的。內容就是合法 crypto-js 的複製品,零惡意程式碼。

為什麼要發一個乾淨版本?在 npm 上建立發佈歷史。一個零歷史的新包突然被大包相依,會觸發安全警報。先「養號」,18 小時後再動手。

T-30 分鐘:發佈 [email protected],注入惡意 postinstall 腳本。

T=0:用被盜的維護者帳號,發佈 [email protected]。

T+39 分鐘:發佈 [email protected]。1.x 和 0.x 兩條版本線,一次全覆蓋。

T+3 小時:npm 下架惡意版本,窗口關閉。

18 小時預埋,39 分鐘把兩條版本線全覆蓋,3 小時後窗口關閉,痕跡自毀。

安全公司 StepSecurity 的評價是「針對 npm Top 10 套件有記錄以來最精密的供應鏈攻擊之一」。

還有個細節:惡意載荷在 npm install 開始後 2 秒內就開始向攻擊者伺服器回傳資訊。比 npm 解析完其他相依還快。你來不及按 Ctrl+C。


在 GitHub 上為什麼看不出來

npm registry 和 GitHub 是兩個獨立系統。你在 GitHub 上看到的程式碼,和你 npm install 裝到的東西,可以完全不是同一個東西。

有維護者的 npm token,就能繞過 GitHub 的程式碼審查、CI/CD、所有你能看到的流程,直接往 registry 發包。

axios 所有合法的 1.x 版本都透過 GitHub Actions 的 OIDC Trusted Publisher 機制發佈,有密碼學簽名,和 GitHub 工作流程綁定。1.14.1 沒有。純手動發佈,沒有 OIDC 綁定,沒有 gitHead。

這個差異寫在 npm registry 的元資料裡。但你平時裝套件的時候查過 registry 元資料嗎?

我也沒查過。


現在該做什麼

用了 axios 的專案,花 5 分鐘跑一遍。

第一步:查 lockfile

打開你的 package-lock.json、pnpm-lock.yaml 或 yarn.lock,搜尋這三個關鍵字:

  • [email protected]
  • [email protected]
  • plain-crypto-js

三個都沒有?大概率安全。後面幾步也值得做。

第二步:清快取

npm cache clean --force

踩坑預警:CI 環境也要清。GitHub Actions、GitLab CI 的 node_modules 快取和 npm 快取裡如果殘留了惡意 tarball,下次建置還會命中。別只清本地。

第三步:鎖死版本

在你的 package.json 或 lockfile 裡明確指定版本,例如:

"axios": "1.14.0"

注意是 "1.14.0",不是 "^1.14.0"。^ 意味著自動升級到最新相容版本,這次恰恰是這個機制讓惡意版本被裝上的。惡意版本雖然已經下架,但顯式鎖定是個好習慣。

第四步:審計 install 腳本

grep -r '"postinstall"' node_modules/*/package.json

這次的載體就是 postinstall。順手看看你其他相依有沒有可疑的 install 腳本。

激進做法:在 .npmrc 裡加上 ignore-scripts=true,全域禁止執行腳本。但 esbuild、sharp 這些套件也靠 postinstall 下載二進位檔案,全禁可能影響建置,自己權衡。

第五步:確認中招了?當作機器已經失控處理

不是「可能要換密碼」。是現在就輪換所有憑證:

  • npm token
  • GitHub token
  • SSH key
  • 資料庫密碼
  • 雲端服務 AK/SK

CI 機器中招的話,檢查 CI secrets 是否外洩。

查異常進程與網路連線,關注 sfrclak.com:8000 這個位址。

RAT 跑起來之後,你機器上的一切對攻擊者都是透明的。別僥倖。


大包不等於安全

很多開發者的直覺是:axios 每週 1 億下載,總不會出事吧。反過來想,越熱門的套件,攻擊者的投入產出比越高。投毒一個每週 100 下載的套件沒人在乎,投毒一個每週 1 億下載的套件,3 小時窗口就夠覆蓋成千上萬個專案。

這次 axios 的原始碼沒有任何問題。

問題出在發佈鏈上。你預設信任的那條從程式碼到 registry 的鏈路,才是該被稽核的東西。lockfile 鎖版本、審計 install 腳本、監控相依變更、關注 registry 元資料的發佈者簽名。不是有空再搞的事。


你的專案查了嗎?留言報個平安。身邊有用 axios 的朋友還不知道這事的,轉給他看一眼。


原文出處:https://juejin.cn/post/7623256350250516518


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝9   💬10   ❤️3
539
🥈
我愛JS
📝2   💬7   ❤️2
145
🥉
💬1  
4
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登