資安指南

安全維運 Next.js:建立不在已公開 CVE 上掉隊的機制

對 Next.js 來說,最大的風險是放任已公開的 CVE 不修補;現實中確實發生過 CVSS 10.0 的 RCE 被放任數月而遭入侵的事故。本文從本站的維運方式,說明四項做法:以實際執行的版本判定、自動監控相依套件、迅速更新、以最小權限執行。

發布於 2026-06-07 更新於 2026-10-06 閱讀時間 4 分鐘
本頁內容

對象:用 Next.js(或類似的 JS 框架)開發並公開應用程式的人,尤其是「靠 AI 幫忙做出來、維運憑感覺」的人。這是從真實事故(→ 放任 CVSS 10.0 的經歷)中整理出來的做法。

本站的看法:重要的不是速度,而是不漏看的機制

個人開發者在安全上做得不夠,大多不是知識不足,而是無法讓維運持續下去。比誰都早讀到 CVE 新聞並沒有價值(速度交給廠商和新聞即可)。真正有效的是讓與自己相關的 CVE 不被漏看的機制。所以本文著重於建立這樣的機制,而不是多知道一些知識。

1. 以實際執行的版本判定

「是否在用危險的版本」,要用實際執行的版本來衡量,而不是清單裡的下限。因為清單上的數字與實際執行的版本常常不一致。

✗ 按 package.json 的下限計算

"next": "^16.0.0" →「16.0.0 有漏洞,所以我們也有」,被高估為 「8 個有漏洞」。

✓ 按實際執行的版本計算

npm ls next 顯示實際解析出的版本 → 已自動升級的是安全的,只有固定版本的會落後。實際是 2 個。

package.json 的下限可能與實際執行的版本不同。以實際執行的版本來判定,風險就會改變(「8 個有漏洞」變成 2 個)。
# see the versions actually resolved
npm ls next react react-dom
# inside a running container
docker exec <container> npm ls next

脫字號範圍(^16.0.0)會在重新建置時自動升級,固定版本的相依套件則會落後。請以這裡顯示的版本來判定。

如何檢查自己的環境

以下步驟能確認你的應用程式實際在執行哪個版本,以及是否受已知 CVE 影響。每一步都只檢查你自己的環境。

1

確認本機的版本

在專案資料夾執行 npx next info。它會顯示 next、react、react-dom 的實際版本,以及距離最新版落後多少。npx next -v 只顯示 Next.js 的版本。

2

查出為什麼是這個版本

npm ls next(或 pnpm why next)會顯示安裝了哪個版本、經由哪個套件引入。如果鎖定檔(package-lock.json 或 pnpm-lock.yaml)沒有 commit,每次建置的版本都可能改變,所以先把它 commit。

3

確認正式環境實際執行的版本

在本機更新,不會改變仍在執行舊映像檔的伺服器。若是容器,讀取執行中容器內 next 的 package.json 的 version 欄位(指令見下)。使用 output: 'standalone' 時也同樣適用。

4

比對已知的 CVE

npm audit --omit=dev 只檢查會部署到正式環境的相依套件。加上 --audit-level=high,發現 High 以上時就會以非零值結束,CI 可以因此停下。用 osv-scanner 掃描鎖定檔也能達到同樣目的。

5

閱讀符合你環境的官方公告

Next.js 的安全公告有時會分 App Router 和 Pages Router,或分自架與託管平台。把公告列出的修復版本,與步驟 1 到 3 查到的版本對照。

# local: actual versions and distance from latest
npx next info
# the version running inside the production container
docker exec <container> node -p "require('next/package.json').version"
# check only production dependencies; fail on High or above
npm audit --omit=dev --audit-level=high

執行方式不同,影響也不同

同一個 CVE,會因你執行 Next.js 的方式而影響或不影響你。以下按部署類型整理兩個過去的案例:

執行方式Middleware 授權繞過(CVE-2025-29927)RSC RCE(CVE-2025-55182)誰負責更新
託管平台(Vercel、Netlify 等)不受影響(路由在另一個系統中執行)使用 App Router 就受影響;有阻擋規則,但仍必須更新你(下一個版本由你的鎖定檔決定)
自架(next start / standalone,含 Docker)受影響使用 App Router 就受影響你(透過重新建置映像檔並重新啟動)
靜態匯出(output: 'export')不受影響(沒有伺服器在執行)沒有伺服器接收請求,一般不會影響你你(建置時的相依套件仍需更新)

所以即使使用託管平台,提升 Next.js 版本仍是你的工作。把平台的保護措施當作在升級到修補版本之前爭取時間。

也要確認支援期限。依官方支援政策,截至 2026 年 10 月:

版本系列狀態(2026 年 10 月)安全修正
16.xActive LTS(功能、修正、安全修補)有
15.xMaintenance LTS(首次發布後兩年)僅限重大問題
14.x 及更舊不受支援嚴重問題時偶爾提供,沒有保證

2. 自動監控相依套件

靠人工追蹤 CVE 撐不下去,而那種遺漏就會變成事故。用工具自動監控。

免費的相依套件監控

osv-scanner scan -L pnpm-lock.yaml

若用 GitHub,就啟用 Dependabot(儲存庫的「Settings」→「Advanced Security」→「Dependabot alerts」)。只有與你的相依套件相符的 CVE 才會以 PR 通知你。

關鍵在於優先順序。本站的立場是:以「是否正被利用(KEV)」乘上「CVSS 有多高」來排序。CVSS 再高,沒用到的元件影響也小;分數中等但正被利用的,則要最優先處理。這種優先順序判斷就是工作的核心。

3. 更新:改用修復版,而不是繞過處理

發現漏洞時,把框架升級到修補版本,修復漏洞本身。

表面處理(不充分)

  • 只在反向代理擋掉看起來像攻擊的請求
  • 停掉扣費或症狀,就當作「處理完畢」
  • RCE 漏洞本身仍然存在

根本修復(正確)

  • 把框架升級到修補版本
  • 升級後,在記錄中確認攻擊特徵已消失
  • 把止住損害與修復根本原因當作兩項獨立的工作,兩者都做

常見的失敗

「停掉了扣費或症狀」≠「處理完畢」。止住損害和修復漏洞是不同的工作。兩者都要做。

實際案例:2025 年 12 月的 React Server Components 漏洞

以下用 2025 年 12 月公開的 React Server Components(RSC)漏洞,說明處理一個已公開的 CVE 實際上是什麼樣子。內容全部來自 React 和 Next.js 的官方公告以及 CISA 的公開資料。

  1. 2025 年 12 月 3 日

    React 公開了 CVE-2025-55182(CVSS 10.0),可能在未經驗證的情況下於伺服器上執行程式碼。在 Next.js 中,15.x、16.x 及部分 canary 版的 App Router 應用程式受影響(CVE-2025-66478);Pages Router 和 Edge Runtime 不受影響。沒有繞過方法,必須升級到修復版本(15.0.5、15.1.9、15.2.6、15.3.6、15.4.8、15.5.7、16.0.7 等)。
  2. 2025 年 12 月 5 日

    CISA 將它加入已確認遭實際利用的漏洞目錄(KEV)。
  3. 2025 年 12 月 6 日

    Next.js 補充說明:截至太平洋時間 12 月 4 日下午 1 點仍在線上且未修補的應用程式,應輪換其使用的機密(API 金鑰等)。
  4. 2025 年 12 月 11 日

    在檢視修補程式的過程中,又在同一機制中發現兩個問題(阻斷服務與原始碼外洩)並修補。之後阻斷服務的修正被證實不完整,因此發布了 CVE-2025-67779,已經升級的人被要求再次升級。

由此得到三點維運上的教訓:

  • 更新一次不代表結束。對同一段程式碼的後續修正,可能相隔幾天就出現
  • 平台的阻擋規則只是補充;官方說明升級是唯一完整的修復方法
  • 如果在修補前就已上線,除了更新之外也要輪換機密

本站的看法:完成的標準是正式環境的版本已修補,而不是執行過更新

像這次一樣後續修正接連出現時,「上週已經升級了」就不再可靠。判斷是否完成,要看正式環境實際執行的版本是否達到最新公告中的修復版本以上,而不是憑對作業的記憶。本站也是在確認容器已重新建立、並檢查容器內執行的版本之後,才把更新標記為完成。

常見錯誤與修正

  • 以 package.json 裡的數字判斷:安裝的版本可能不同。用 npx next info 或 npm ls next 確認。
  • 更新完鎖定檔就停下:在正式環境的映像檔重新建置並重新啟動之前,舊版本會繼續執行。確認正式環境內的版本。
  • 更新一次就覺得安全:可能還會有後續公告。保持 Dependabot 等通知開啟,並在幾天內持續關注公告。
  • 交給平台的阻擋規則:它們不一定能擋下所有形式的攻擊。請升級。
  • 停留在不受支援的版本系列:14.x 及更舊版本的修正沒有保證。規劃升級到 16.x。
  • 在只用於開發的雜訊中漏看與正式環境相關的警告:先執行 npm audit --omit=dev,看會部署出去的部分。
  • 忽略修補之前的那段期間:機密可能在那段時間被取走。輪換 API 金鑰和資料庫密碼(→ .env 和 API 金鑰的基礎)。

4. 用最小權限限制損害

設計成即使應用程式被利用,損害也能被限制住。

1

以非特權使用者執行

不要把容器的 USER 設為 root。這樣即使被入侵,影響也只限於該使用者被允許做的事。
2

DB/Redis 只綁定內部網路

絕不對外公開。減少能被直接觸及的範圍。
3

按服務隔離

把網路和資料按服務拆開,讓一處被入侵不會擴散到全部。

這些決定了入侵最後是止於「竊取容器內的 env」,還是一路到「主機被接管」。

本站自己也這樣做

本站也按本文所寫,監控自己相依套件的 CVE,讓當初那種遺漏(放任已公開的 CVSS 10.0)不再只靠人的注意力。我們之所以寫「按優先順序(KEV+CVSS)來看」,是因為我們實際上就是這樣維運的。

延伸閱讀

出處

  • Next.js「Security Advisory: CVE-2025-66478」(2025 年 12 月 3 日;12 月 6 日更新):nextjs.org
  • Next.js「Security Update: December 11, 2025」(CVE-2025-55183 / 55184 / 67779):nextjs.org
  • NVD「CVE-2025-55182」:nvd.nist.gov / CISA「Known Exploited Vulnerabilities Catalog」:cisa.gov
  • Vercel「React2Shell Security Bulletin」:vercel.com
  • Vercel「Postmortem on Next.js Middleware bypass」(CVE-2025-29927):vercel.com
  • Next.js「Support Policy」:nextjs.org / 「next CLI」:nextjs.org / 「Static Exports」:nextjs.org
  • npm Docs「npm audit」:docs.npmjs.com / OSV-Scanner「Usage」:google.github.io / GitHub Docs「Configuring Dependabot alerts」:docs.github.com

FAQ

QNext.js 的安全裡最重要的是什麼?
A

比起自己不寫出 bug,更重要的是不要放任框架本體或相依套件中已公開的 CVE 不修補。多數嚴重事故並非來自新型攻擊,而是來自被放任的已知漏洞。

Q看 package.json 就能判斷是否有漏洞嗎?
A

不能。package.json 裡的 `^`(下限)不反映實際情況:脫字號範圍會在重新建置時自動升級,固定版本的相依套件則會落後。請務必以實際執行的版本來判定。

Q個人開發該最先做的一件事是什麼?
A

啟用 Dependabot(GitHub)或 osv-scanner,自動監控相依套件的 CVE。人工檢查一定會有遺漏。能持續運作的機制,比多知道一些知識更有價值。

Q怎麼確認自己用的是哪個 Next.js 版本?
A

在專案資料夾執行 `npx next info`,會顯示 next、react、react-dom 的實際版本。正式環境則要讀取執行中的容器或伺服器內 next 的 package.json 版本(本文的步驟 3)。本機和正式環境不一定相同,兩邊都要確認。

Q如果部署在 Vercel 之類的平台上,還需要自己更新嗎?
A

需要。2025 年 3 月的 middleware 授權繞過漏洞(CVE-2025-29927)不影響 Vercel 和 Netlify,但 2025 年 12 月的 React Server Components RCE(CVE-2025-55182)普遍影響使用 App Router 的應用程式。Vercel 加入了自己的阻擋規則(WAF),但也表示無法擋下所有變體,升級到修補版本是必要的。

Q繼續使用 Next.js 14 或更舊的版本可以嗎?
A

不建議。依官方支援政策,14.x 及更舊版本已不受支援;安全修正只會在嚴重問題時偶爾提供,且沒有保證。截至 2026 年 10 月,受支援的是 16.x(Active LTS)和 15.x(Maintenance LTS)。Maintenance 期間為首次發布後兩年,所以如果你在用 15.x,也要規劃升級到 16.x。