網頁開發

npm v12 預設關掉 install scripts:十年供應鏈攻擊的總清算,你的 CI 七月可能會壞

2026.06.13 · 24 次瀏覽
npm v12 預設關掉 install scripts:十年供應鏈攻擊的總清算,你的 CI 七月可能會壞

GitHub 宣布 npm v12 三項 breaking changes:依賴的 install scripts、Git 依賴、遠端 URL 依賴全部預設封鎖——這是對 event-stream 到 Shai-Hulud 十年蠕蟲史的正面回應

分享:

6 月 9 日,GitHub 在官方 Changelog 發布〈Upcoming breaking changes for npm v12〉,預告 7 月上線的 npm v12 將把三件事改成「預設禁止」:依賴套件的 preinstallinstallpostinstall scripts 不再自動執行、Git 依賴與遠端 URL tarball 依賴不再解析,除非你逐項明確允許。接下來幾天 The Hacker News、BleepingComputer 接連跟進報導,這是 npm 史上對預設行為最大的一次外科手術。

要理解這刀為什麼砍得這麼深,得回看十年的供應鏈攻擊史:2018 年 event-stream 後門、2021 年 ua-parser-js 挖礦木馬,到 2025 年自我複製的 Shai-Hulud 蠕蟲——幾乎每一次的感染入口都是同一個:postinstall script 在你打 npm install 的瞬間,以你的權限執行任意程式碼。過去的防線是開發者自律加上 --ignore-scripts 旗標,但那是 opt-in;npm v12 把方向整個翻過來,從「預設執行、自己關」變成「預設封鎖、自己開」。

影響範圍沒有懸念:npm registry 每週服務數百億次下載,任何一個有 node_modules 的專案都在射程內——包括每一個用 Vite 打包前端的 Laravel 專案。依賴原生編譯(node-gyp)、sharp、esbuild、husky 這類靠 install script 工作的套件,七月起在乾淨環境會直接不執行 script,CI pipeline 與 Docker build 是第一波斷裂點。

下面拆解三項變更的確切行為、npm approve-scripts 的遷移指令,以及 npm 12 與 pnpm、Bun、Yarn 的取捨。

技術細節 + CLI

  • 依賴的 install scripts 預設不執行(你自己專案 root 的 scripts 不受影響)
  • Git 依賴(直接或間接)需 --allow-git 才解析
  • 遠端 URL tarball 依賴需 --allow-remote 才解析

npm 官方文件,建議的遷移路徑是先升級到 npm 11.16.0 之後的版本,跑一次安裝看警告,再逐項放行:

# 先模擬 v12 行為,今天就能測
npm install --ignore-scripts
 
# 升級到 11.16.0+,安裝時會列出「將被封鎖」的 scripts
npm install -g npm@11
npm install
 
# 檢視待審核的套件 scripts,放行你信任的
npm approve-scripts --allow-scripts-pending

放行結果會寫進 package.json,進版本控制、過 code review——信任決策第一次變成可稽核的 diff。

三類讀者的立刻行動

  • 工程師:本週在 CI 加一條 npm install --ignore-scripts 的 job,列出會壞的套件清單;檢查 sharp、esbuild、puppeteer、husky 等重度依賴 install script 的套件。
  • 技術負責人:把「npm 12 相容性」排進 6 月 sprint;Docker base image 與 CI runner 的 npm 版本要釘住,避免 7 月被動升級炸掉部署;同步盤點 lockfile 內的 Git/URL 依賴存量。
  • 創業者/接案商:問你的維護廠商一句話:「我們的專案七月 npm 12 上線後還能 build 嗎?」答不出來,就是你需要維護合約的證據。

比較與權衡

方案優點缺點遷移成本
npm 12(預設封鎖)官方標準、allow 清單進 package.json 可稽核7 月起 CI 首當其衝、生態適應期混亂低:跑 approve-scripts、改 CI(0.5-1 工作日/專案)
pnpm 10+2025 年初起即同樣預設、生態驗證過lockfile 不相容 npm中:換 lockfile 與 CI 快取(1-2 工作日)
Bun安裝極快、預設只信任白名單套件 scriptsruntime 相容性仍有邊角、企業採用保守中-高:需驗證整條 build chain
Yarn BerryPnP 模式根本沒有 node_modules 可感染學習曲線陡、舊套件相容問題多高:架構級遷移(3-5 工作日起)

不會告訴你的事

  • 封鎖 install scripts 擋不住 require-time 攻擊:惡意程式碼搬進模組本體,在你 import 的那一刻照樣執行。這次砍掉的是「最方便」的入口,不是「唯一」的入口。
  • 「允許清單疲勞」是新風險:當開發者習慣無腦 approve,攻擊者只要寄生在「大家一定會放行」的熱門套件相依樹裡就好。安全預設值轉移了攻擊成本,沒有消滅它。

未來 3 個月會發生什麼

7 月 npm 12 GA 後,預期第一週會出現大量 CI 災情文與「怎麼全部放行」的錯誤教學;主流框架(Next.js、Vite、Laravel 生態的 npm 工具鏈)會陸續發布官方 allow 清單建議。觀察指標:npm approve-scripts 的 DX 是否好用到讓人不想繞過,以及 pnpm 是否藉機再吃一波市佔。

常見問題 FAQ

我的專案會不會壞?怎麼最快確認?

在本機或 CI 跑 npm install --ignore-scripts 後執行完整 build 與測試。會壞的幾乎都集中在原生編譯(node-gyp)與下載 binary 的套件(sharp、puppeteer、esbuild)。

我自己專案的 build script 會被擋嗎?

不會。封鎖的是「依賴套件」的 lifecycle scripts;你專案 root 的 package.json scripts(dev、build、postinstall)照常執行。

用 pnpm 的團隊需要做什麼?

基本不用動,pnpm 10 起已是同樣的預設。這次是 npm 向 pnpm 的安全模型看齊。

Laravel + Vite 專案受影響嗎?

受影響的是前端依賴層。Vite 本身無 install script 依賴問題,但其相依樹中的 esbuild 等需要放行;上線前先在 staging 驗證 npm ci 全流程。

我的觀點

主流敘事是「npm 終於安全了」,我的判斷相反:最危險的窗口正是變更上線後的前六個月。安全預設值給了團隊「已經處理完」的錯覺,但攻擊面只是移到 require-time 與 allow 清單的審核品質上;而大量團隊會在 CI 壞掉的壓力下,用「全部放行」的 workaround 把防線自己拆掉——壓力下做的安全決策,通常是最差的安全決策。對 ScriptWalker 的業務啟示:這是一個有明確截止日(7 月)的健檢商機——對所有維護合約客戶主動提供「npm 12 相容性掃描」,一次掃描、一張報告、一個 approve 清單 PR,把一次性的生態變動轉成可收費的看護價值。

資料來源

分享: