跳到正文
DEV Community· Waseem Anjum·· 2 小時前精選AI 評分83

Next.js 2026 年 10 月安全更新修補 use cache、SVG sharp RCE 及 Server Actions DoS

Next.js Security Update October 2026: Patch the use cache RCE, SVG sharp RCE and Server Actions DoS

AI 導讀

Next.js 於 2026 年 10 月 14 日發布的安全更新修補兩項未經身份驗證的遠端程式碼執行漏洞,以及一項 Server Actions 拒絕服務(DoS)漏洞。

推薦理由

文章把漏洞版本對照、sharp 獨立檢查與容器內驗證串成修補流程,並記錄 npm audit 對未修補版本回報零漏洞的實測結果。

正文 · 繁體中文

2026 年 10 月 14 日的 Next.js 安全更新修復了三個漏洞:兩個嚴重的未經驗證遠端程式碼執行(RCE)漏洞,分別出現在 use cache 和透過 sharp 進行的 SVG 圖片最佳化;以及一個高嚴重程度、影響 Server Actions 的阻斷服務漏洞。使用 16.x 的用戶請升級至 Next.js 16.4.1 或更新版本,使用 15.x 的用戶請升級至 15.5.28;並確保 sharp 為 0.35.5 或更新版本,然後重新建置及重新部署。

修補程式容易套用,但自行代管時也很容易出錯。我在實際安裝環境重現了升級過程,發現將 Next.js 15 升級至 15.5.28 後,仍會保留有漏洞的 sharp 0.34.5;而在未修補的 next@16.4.0 上,npm audit 則回報 0 個漏洞。本指南會説明如何檢查是否受影響,提供一個可代為檢查的指令碼,並列出修補 Docker 或 Coolify 部署的確切步驟。所有內容均附有官方公告來源。

2026 年 10 月的 Next.js 安全更新修復了哪些問題?

根據Next.js 官方安全更新,更新修復了 2026 年 10 月 14 日發布的三項安全公告,並在 Next.js 16.4.1(Active LTS)和 15.5.28(Maintenance LTS)中全部修補。其中兩項漏洞可讓攻擊者在未經驗證的情況下遠端執行程式碼,CVSS 4.0 評分為 9.5;第三項則可讓精心構造的請求令伺服器 CPU 使用率持續滿載。

安全公告 嚴重程度 問題 受影響的 next 版本 修復版本 緩解方法
GHSA-673q-mjm6-r5xr 嚴重,9.5 use cache 函式在返回多個型別化陣列時出現的 RCE 16.0.0 至 16.4.0 16.4.1 無
CVE-2026-96889 / GHSA-2464-fhr4-w9xw 嚴重,9.5 在使用 glibc 的 Linux 上,透過 sharp 的 librsvg 處理 SVG 時,Image Optimization API 出現 RCE 10.0.0 至 15.5.27,16.0.0 至 16.4.0 15.5.28, 16.4.1 sharp 0.35.5 或更新版本
GHSA-p3m5-59mp-jv5r 高,8.2 DoS:精心構造的請求會令使用 Server Actions 的 App Router 應用程式消耗過多 CPU 13.0.0 至 15.5.27,16.0.0 至 16.4.0 15.5.28, 16.4.1 無

React Server Components 的兩個漏洞亦有 React 上游安全公告:GHSA-xqc2-xf4c-x3h3 涉及型別化陣列 RCE,GHSA-h3gv-c5rc-p453 則涉及 DoS。Next.js 在 next 套件中附有自行編譯的 react-server-dom-webpack 和 react-server-dom-turbopack 版本(我檢查了 node_modules/next/dist/compiled),因此修復 Next.js 應用程式的方法是升級 next,而不是隻升級 react。

快速詞彙説明

術語 含義
RCE 遠端程式碼執行:攻擊者可在你的伺服器上執行程式碼
DoS 阻斷服務:伺服器停止回應正常請求
GHSA GitHub 安全公告的識別碼
sharp Next.js 用於 Image Optimization 的圖片程式庫;內含 libvips 和 librsvg
glibc Debian、Ubuntu 及 node:*-slim 映像檔使用的 C 程式庫(Alpine 則使用 musl)
Active / Maintenance LTS Next.js 16.4.x 和 15.5.x,兩個會接收安全修補的版本系列

簡而言之:立即修補 Next.js

  1. 升級:使用 16.x 的用戶請升級至 npm install next@16.4.2(16.4.1 是安全更新版本;16.4.2 加入錯誤修正),使用 15.x 的用戶請升級至 npm install next@15.5.28。
  2. 檢查 sharp:執行 npm ls next sharp,並確認版本為 sharp@0.35.5 或更新版本。在 15.x 上,如果仍顯示 0.34.x,請執行 npm update sharp。
  3. 提交鎖定檔,從頭重新建置映像檔並重新部署。
  4. 確認正在執行的容器,而不只是手提電腦上的版本。

Decision chart: check the installed next version, then the three advisories with their affected versions, exposure conditions and workarounds, and the fix of next 16.4.1 or 15.5.28 with sharp 0.35.5

我的 Next.js 應用程式是否受影響?

如果已安裝的 next 版本為 16.0.0 至 16.4.0,或為 15.5.27 或更早版本;又或者 Next.js 載入的 sharp 版本早於 0.35.5,你的應用程式便會受影響。實際會受哪些漏洞影響,取決於所用功能:use cache 需要使用 Cache Components,DoS 需要至少一個 Server Action,而 SVG 漏洞則需要使用 glibc 的 Linux。

先檢查版本:

npm ls next sharp

然後逐項對照安全公告,確認你的應用程式是否受影響:

  • use cache 遠端程式碼執行 (RCE) (GHSA-673q-mjm6-r5xr)。 只有使用 App Router 並啟用 Cache Components 的 Next.js 16 應用程式才可能受影響,而觸發條件是 use cache 函式傳回多個型別化陣列。安全公告仍表示,即使應用程式沒有類似函式,也應立即升級。從 create-next-app 16.4 起,新應用程式預設會啟用 Cache Components,詳情可參閲我介紹過的Next.js use cache 詳解。
  • SVG 圖片最佳化遠端程式碼執行 (CVE-2026-96889)。 sharp 用來解碼 SVG 的 librsvg 存在記憶體錯誤,在以 glibc 為基礎的 Linux 上執行 Next.js 時,可能導致遠端程式碼執行。大部分以 Debian 和 Ubuntu 為基礎的 Docker 映像及 VPS 安裝都受影響。Next.js 預設不會最佳化 SVG 圖片;設定了 images.dangerouslyAllowSVG: true 的應用程式最明顯會受影響,但安全公告並未限定於這項設定,因此無論如何都應安裝修補程式。
  • Server Actions 拒絕服務攻擊 (GHSA-p3m5-59mp-jv5r)。 使用 Next.js 13 至 15.5.27 或 16.0.0 至 16.4.0,且至少有一個 Server Action 的任何 App Router 應用程式都受影響。Pages Router 應用程式及沒有 Server Actions 的應用程式則不受影響。

為甚麼 npm audit 説我的應用程式安全?

因為它讀取的安全公告資訊來源可能尚未列出這些問題。2026 年 10 月 17 日,我在一個空白專案中安裝了 next@16.4.0、react 和 react-dom,並執行 npm audit:

$ npm audit --json | jq .metadata.vulnerabilities
{ "info": 0, "low": 0, "moderate": 0, "high": 0, "critical": 0, "total": 0 }

在仍有兩項未解決的嚴重級別安全公告的版本上,結果竟然是零項發現。請把 npm audit、Dependabot 及類似掃描工具視為輔助檢查,並自行核對版本,或使用下方的指令碼。

用來檢查應用程式是否受三項安全公告影響的指令碼

我編寫這個指令碼來檢查自己執行的每個應用程式。它會讀取已安裝的 next 版本,從 Next.js 自己的資料夾解析 sharp(即圖片最佳化器實際載入的副本),掃描原始碼中的 use cache、use server 和 dangerouslyAllowSVG,並在發現任何未安裝修補程式的項目時以代碼 1 結束,因此你可以將它加入 CI。它沒有任何相依項目。

// check-next-security.mjs: checks a Next.js app against the October 14, 2026 advisories.
// Usage: node check-next-security.mjs [projectDir]
import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs'
import { createRequire } from 'node:module'
import path from 'node:path'

const dir = path.resolve(process.argv[2] ?? '.')
const req = createRequire(path.join(dir, 'package.json'))
// Find node_modules/<pkg>/package.json the way Node would, without relying on "exports".
const version = (pkg, from = req) => {
  for (const base of from.resolve.paths(pkg) ?? []) {
    const file = path.join(base, pkg, 'package.json')
    if (existsSync(file)) return JSON.parse(readFileSync(file, 'utf8')).version
  }
  return null
}
const cmp = (a, b) => {
  const [x, y] = [a, b].map((v) => v.split('-')[0].split('.').map(Number))
  for (let i = 0; i < 3; i++) if (x[i] !== y[i]) return x[i] - y[i]
  return 0
}
const inRange = (v, lo, hi) => cmp(v, lo) >= 0 && cmp(v, hi) <= 0

// Scan source files for features the advisories depend on.
const src = []
const walk = (d) => {
  for (const name of readdirSync(d)) {
    if (['node_modules', '.next', '.git', 'out', 'dist'].includes(name)) continue
    const p = path.join(d, name)
    if (statSync(p).isDirectory()) walk(p)
    else if (/\.(m?[jt]sx?)$/.test(name)) src.push(readFileSync(p, 'utf8'))
  }
}
walk(dir)
const code = src.join('\n')
const uses = {
  useCache: /['"]use cache(: \w+)?['"]/.test(code),
  serverActions: /['"]use server['"]/.test(code),
  svgOptimizer: /dangerouslyAllowSVG\s*:\s*true/.test(code),
  nextOg: /from ['"]next\/og['"]/.test(code),
}

const next = version('next')
if (!next) { console.error('next is not installed in', dir); process.exit(2) }
// Resolve sharp from next's own folder, since that is the copy the image optimizer loads.
const nextPkg = (req.resolve.paths('next') ?? []).map((b) => path.join(b, 'next', 'package.json')).find(existsSync)
const sharp = version('sharp', createRequire(nextPkg))
const major = Number(next.split('.')[0])

const checks = [
  {
    id: 'GHSA-673q-mjm6-r5xr (critical): RCE in use cache returning typed arrays',
    vulnerable: inRange(next, '16.0.0', '16.4.0'),
    fix: 'upgrade next to 16.4.1+ (no workaround)',
    note: uses.useCache ? 'app uses "use cache"' : 'no "use cache" found, upgrade anyway',
  },
  {
    id: 'CVE-2026-96889 / GHSA-2464-fhr4-w9xw (critical): RCE via SVG in image optimization',
    vulnerable: sharp ? cmp(sharp, '0.35.5') < 0 : false,
    fix: 'sharp must be 0.35.5+ (npm update sharp), next 16.4.1+ or 15.5.28+',
    note: `sharp ${sharp ?? 'not installed'}` + (uses.svgOptimizer ? ', dangerouslyAllowSVG on' : '') + (uses.nextOg ? ', uses next/og' : ''),
  },
  {
    id: 'GHSA-p3m5-59mp-jv5r (high): DoS via Server Actions',
    vulnerable: inRange(next, '13.0.0', '15.5.27') || inRange(next, '16.0.0', '16.4.0'),
    fix: major >= 16 ? 'upgrade next to 16.4.1+' : 'upgrade next to 15.5.28+',
    note: uses.serverActions ? 'app defines Server Actions' : 'no "use server" found',
  },
]

console.log(`next ${next}, sharp ${sharp ?? 'not installed'} in ${dir}\n`)
let bad = 0
for (const c of checks) {
  if (c.vulnerable) bad++
  console.log(`${c.vulnerable ? 'VULNERABLE' : 'ok        '}  ${c.id}`)
  console.log(`            ${c.note}${c.vulnerable ? `\n            fix: ${c.fix}` : ''}`)
}
console.log(bad ? `\n${bad} issue(s) found. Patch, rebuild and redeploy.` : '\nAll three October 14, 2026 advisories are patched.')
process.exit(bad ? 1 : 0)

在專案根目錄執行 node check-next-security.mjs 即可。以下是在一個有一個 use cache 函式和一個 Server Action 的 Next.js 16.4.0 應用程式上,執行 npm install next@16.4.2 前後的實際輸出:

$ node check-next-security.mjs
next 16.4.0, sharp 0.35.4 in /app

VULNERABLE  GHSA-673q-mjm6-r5xr (critical): RCE in use cache returning typed arrays
            app uses "use cache"
            fix: upgrade next to 16.4.1+ (no workaround)
VULNERABLE  CVE-2026-96889 / GHSA-2464-fhr4-w9xw (critical): RCE via SVG in image optimization
            sharp 0.35.4
            fix: sharp must be 0.35.5+ (npm update sharp), next 16.4.1+ or 15.5.28+
VULNERABLE  GHSA-p3m5-59mp-jv5r (high): DoS via Server Actions
            app defines Server Actions
            fix: upgrade next to 16.4.1+

3 issue(s) found. Patch, rebuild and redeploy.

$ npm install next@16.4.2 && node check-next-security.mjs
next 16.4.2, sharp 0.35.5 in /app

ok          GHSA-673q-mjm6-r5xr (critical): RCE in use cache returning typed arrays
            app uses "use cache"
ok          CVE-2026-96889 / GHSA-2464-fhr4-w9xw (critical): RCE via SVG in image optimization
            sharp 0.35.5
ok          GHSA-p3m5-59mp-jv5r (high): DoS via Server Actions
            app defines Server Actions

All three October 14, 2026 advisories are patched.

這個指令碼會檢查版本和原始碼模式,並非漏洞利用測試。結果乾淨代表你使用的是已安裝修補程式的版本,這正是安全公告要求的做法。

如何將 Next.js 16 升級至已修補的版本?

安裝最新的 16.4 修補版本,然後確認 sharp 亦隨之更新。Next.js 16.4.1 將 sharp 的要求提高至 ^0.35.5(16.4.0 接受 ^0.35.4;兩者的資料均來自 npm 登錄檔),因此升級 next 時,npm 亦必須升級 sharp。

npm install next@16.4.2
npm ls next sharp

在我的測試中,一個鎖定檔記錄了 next@16.4.0 和 sharp@0.35.4 的專案,執行 npm install next@16.4.1 後得到 sharp@0.35.5,結果符合預期。如果你使用這些套件管理工具,亦可用 pnpm why sharp 或 yarn why sharp 執行相同檢查。

eslint-config-next 的版本應與 next 相符,因此應在同一個提交中一併升級。如果你尚未升級至 16,版本 16 升級指南涵蓋了重大變更;這項工作比安裝修補程式更繁複,因此請先為 15.x 安裝修補程式。

如何安全地為 Next.js 15 安裝修補程式?

升級至 15.5.28,然後另外檢查 sharp,因為單獨升級 next 未必能修正 SVG 漏洞。Next.js 15.5.28 將 sharp 宣告為 ^0.34.3 || ^0.35.5,因此,若現有鎖定檔已解析出 sharp 0.34.x,仍符合要求,而 npm 會保留該版本。

以下是在一個鎖定檔中有 next@15.5.27 和 sharp@0.34.5 的實際專案上發生的情況:

$ npm install next@15.5.28
$ npm ls sharp
└─┬ next@15.5.28
  └── sharp@0.34.5        # still vulnerable

$ npm update sharp
$ npm ls sharp
└─┬ next@15.5.28
  └── sharp@0.35.5        # fixed

如果 sharp 是 package.json 中的直接相依項目,請改為執行 npm install sharp@0.35.5。如要在整個 monorepo 強制使用同一個版本,請加入 override:

{
  "overrides": {
    "sharp": "0.35.5"
  }
}

pnpm 使用 pnpm.overrides,Yarn 則使用 resolutions 來執行相同操作。

如何為 Docker 或 Coolify 中自行託管的 Next.js 應用程式安裝修補程式?

更新鎖定檔,以不重用舊圖層的方式重新建置映像檔,重新部署,然後檢查正在運行的容器內的版本。只有當處理流量的容器包含依賴項修正時,修正才會真正提供保護;Docker 建置會複製package-lock.json並執行npm ci,準確安裝鎖定檔列明的內容。

Six-step patch flow for self-hosted Next.js: update deps, check the lockfile, commit it, rebuild the image, redeploy with Coolify or docker compose, and verify the versions inside the container

  1. 在本機更新並驗證。 npm install next@16.4.2、npm ls next sharp,然後執行檢查工具。
  2. 提交package-lock.json。 沒有它,建置伺服器便會採用上次解析出的結果。
  3. 重新建置映像檔。 在我用於正式環境的 Next.js Dockerfile中,採用 standalone 輸出時,next build會把sharp及其原生 libvips 套件複製到.next/standalone/node_modules。在我的建置中,這個位置是@img/sharp-libvips-linux-x64,即 glibc 版本。修補前建置的映像檔會一直保留舊的sharp,直到你重新建置為止。
  4. 重新部署。 在 Coolify 中,推送提交或按一下Redeploy。若要在這次建置中略過快取圖層,可觸發強制部署,例如透過 Coolify API 使用GET /api/v1/deploy?uuid=<app-uuid>&force=true。我的使用 Coolify 自行託管 Next.js 指南介紹了部署設定。若使用一般 Docker,請執行docker compose build --no-cache && docker compose up -d。
  5. 驗證正在運行的容器。 standalone 映像檔中的應用程式位於/app,因此:
docker exec <container> node -e "console.log(require('/app/node_modules/next/package.json').version, require('/app/node_modules/sharp/package.json').version)"

即使sharp 0.35.5 沒有匯出./package.json,仍可透過絕對路徑 require package.json檔案。我在 Next.js 16.4.2 的 standalone 建置中執行了相同指令;它針對sharp和next輸出0.35.5 16.4.2。如果你的 Dockerfile 把應用程式複製到/app以外的位置,請相應調整路徑。

如果今天無法升級 Next.js,怎麼辦?

目前只有 SVG 漏洞有暫行緩解方法;use cache RCE 和 Server Actions DoS 均沒有可用的緩解方法,因此應在幾小時內,而不是幾星期後完成升級。此期間:

漏洞 暫行措施 來源
SVG / sharp RCE 即使不升級next,也要確保sharp為 0.35.5 或更新版本 Next.js 安全公告
SVG / sharp RCE 在你自己的程式碼中,若有呼叫sharp,請使用sharp.block({ operation: ['VipsForeignLoadSvg'] })封鎖 SVG 解碼 sharp 安全公告
SVG / sharp RCE 如果不需要最佳化 SVG,請停用images.dangerouslyAllowSVG Image 文件
use cache RCE 沒有。請升級。 Next.js 安全公告
Server Actions DoS 沒有。請升級。速率限制只能縮小影響範圍。 Next.js 安全公告

我使用sharp 0.35.5 測試了sharp.block呼叫:升級前,小型 SVG 會轉換成 100-byte PNG;升級後,相同呼叫則因Input buffer contains unsupported image format而失敗。

import sharp from 'sharp'

// Refuse to decode SVG input anywhere this sharp instance is used.
sharp.block({ operation: ['VipsForeignLoadSvg'] })

sharp 安全公告補充了一項強化安全性的注意事項:librsvg 漏洞能否導致程式碼執行,部分取決於 Node.js 二進制檔。公告建議使用以位置獨立可執行檔(PIE)方式建置的node,並指出大多數 Linux 發行版套件已符合此要求,但官方 Node.js 執行檔則不是。

如何判斷自己是否受到攻擊?

安全公告沒有公佈入侵指標,也沒有提及漏洞已在實際環境中遭利用,因此請留意各漏洞可能留下的副作用,並重新查看安全公告是否有更新。

  • DoS: Next.js 程序持續佔用 100% CPU,同時請求緩慢或失敗,尤其是帶有Next-Action標頭的POST請求。
  • SVG RCE:使用.svg來源、發往/_next/image的異常請求;圖片最佳化期間 Node.js 程序崩潰;以及容器出現新的子程序或對外連線。
  • 任何 RCE:容器檔案系統內出現不明檔案、環境變數遭更改,或機密資料從新的 IP 位址被使用。如果發現任何上述情況,請在修補後輪替機密資料(資料庫 URL、API 金鑰、NEXT_SERVER_ACTIONS_ENCRYPTION_KEY)。

讓下次修補更快完成的安全習慣

這是一次非例行發布,在 16.4.0 於 10 月 6 日推出八天後發布。養成幾個習慣,可令下次處理只需十分鐘:

  • 使用 LTS 版本系列。安全修正會在 16.4.x(Active LTS)和 15.5.x(Maintenance LTS)推出。
  • 開啟升級提示。Next.js 16.4 新增了 experimental.agentUpgrade,其預設的 'security' 政策會在 next dev 和 next build 期間,於升級可修正你所安裝版本中已知漏洞時提醒你(Next.js 16.4 説明)。
  • 在 CI 中執行檢查工具。如果安裝了有漏洞的版本,結束代碼 1 會令建置失敗。
  • 固定版本並提交鎖定檔,然後根據鎖定檔重新建置映像檔,確保執行中的版本就是你檢查過的版本。
  • 精簡並保護 Server Actions。這項 DoS 攻擊只需要有一個 action 存在;不過,驗證身分和輸入驗證可限制未來任何漏洞能觸及的範圍;詳情請參閲 Server Actions 與 Route Handlers 的比較。

修補時常見的錯誤

錯誤 結果 修正方法
升級 react 而非 next Next.js 會保留其內置的 RSC 執行階段 升級 next
將 15.x 升級至 15.5.28 後便停止 sharp 0.34.x 仍可能留在鎖定檔中 npm update sharp,確認版本為 0.35.5 或以上
相信 npm audit 它在未修補的 16.4.0 上報告沒有問題 檢查版本或執行指令碼
沒有提交鎖定檔 CI 或 Coolify 會重新建置舊版本 提交 package-lock.json
從快取層重新建置 舊的 node_modules 層會被重用 停用快取建置一次
只檢查手提電腦 正式環境仍在執行舊映像檔 在執行中的容器內執行 docker exec

相關內容:我已將上面的檢查指令碼打包成可重複使用的 Agent skill,讓 Claude Code、Cursor、Codex 或 Copilot 為你執行檢查及修補。請參閲 Agent Skills:如何撰寫 SKILL.md。

相關內容:在 Next.js 應用程式旁運行 MCP 伺服器?2026 年 MCP 安全介紹本月 MCP SDK 的 OAuth 安全公告,以及如何修正。

重點摘要

  • 2026 年 10 月 14 日的更新修正了兩個嚴重的 RCE 漏洞(涉及 use cache 型別化陣列,以及透過 sharp 的 SVG),以及一個高危險度的 Server Actions DoS 漏洞。
  • 已修補的版本為 Next.js 16.4.1+ 和 15.5.28+,並須使用 sharp 0.35.5 或更新版本。
  • 在 15.x 上,升級 next 可能會令 sharp 0.34.x 留在已安裝的版本中;請執行 npm update sharp 並確認版本。
  • npm audit 在 2026 年 10 月 17 日沒有回報未修補的 next@16.4.0 存在問題,因此請直接檢查版本。
  • 自行託管的修正只有在重新建置映像檔、重新部署,並確認執行中容器內的版本後才算完成。

原文刊載於 fabwaseem.com。

來源:DEV Community · dev.to