Next.js Security Update October 2026: Patch the use cache RCE, SVG sharp RCE and Server Actions DoS
The October 14, 2026 Next.js security update fixes two critical RCEs (use cache and SVG via sharp) and a Server Actions DoS. Check if you are affected, run a free checker script, and patch Next.js 15 and 16 on Docker or Coolify.

On this page
The Next.js security update of October 14, 2026 fixes three vulnerabilities: two critical unauthenticated remote code execution (RCE) bugs, one in use cache and one in SVG image optimization through sharp, and a high severity denial of service in Server Actions. Upgrade to Next.js 16.4.1 or later on 16.x, or 15.5.28 on 15.x, make sure sharp is 0.35.5 or later, then rebuild and redeploy.
The patch is easy to apply and easy to get wrong when you self-host. I reproduced the upgrade on real installs and found that upgrading Next.js 15 to 15.5.28 left the vulnerable sharp 0.34.5 in place, while npm audit on an unpatched next@16.4.0 reported 0 vulnerabilities. This guide shows how to check whether you are affected, a script that checks for you, and the exact steps to patch a Docker or Coolify deployment. Everything is cited to the official advisories.
What did the October 2026 Next.js security update fix?#
It fixed three advisories published on October 14, 2026, all patched in Next.js 16.4.1 (Active LTS) and 15.5.28 (Maintenance LTS), according to the official Next.js security update. Two allow unauthenticated remote code execution with a CVSS 4.0 score of 9.5; the third lets crafted requests pin a server's CPU.
The two React Server Components bugs also have upstream React advisories: GHSA-xqc2-xf4c-x3h3 for the typed-array RCE and GHSA-h3gv-c5rc-p453 for the DoS. Next.js ships its own compiled copy of react-server-dom-webpack and react-server-dom-turbopack inside the next package (I checked node_modules/next/dist/compiled), so upgrading next is what fixes a Next.js app, not bumping react alone.
Quick definitions#
TL;DR: how to patch Next.js now#
- Upgrade:
npm install next@16.4.2on 16.x (16.4.1 is the security release; 16.4.2 adds bug fixes) ornpm install next@15.5.28on 15.x. - Check
sharp: runnpm ls next sharpand confirmsharp@0.35.5or later. On 15.x, runnpm update sharpif it still shows 0.34.x. - Commit the lockfile, rebuild the image from scratch and redeploy.
- Verify the running container, not just your laptop.

Is my Next.js app affected?#
You are affected if your installed next is 16.0.0 through 16.4.0, or 15.5.27 and earlier, or if the sharp copy Next.js loads is older than 0.35.5. Which bugs reach you depends on features: use cache needs Cache Components, the DoS needs at least one Server Action, and the SVG bug needs glibc Linux.
Check the versions first:
npm ls next sharpThen match your app against each advisory:
use cacheRCE (GHSA-673q-mjm6-r5xr). Only Next.js 16 apps using the App Router with Cache Components can be exposed, and the trigger is ause cachefunction that returns multiple typed arrays. The advisory still says to upgrade immediately even if your application does not have similar functions. New apps fromcreate-next-app16.4 have Cache Components on by default, as I covered in Next.js use cache explained.- SVG Image Optimization RCE (CVE-2026-96889). A memory bug in librsvg, which
sharpuses to decode SVG, can lead to RCE when Next.js runs on glibc-based Linux. That covers most Debian and Ubuntu based Docker images and VPS installs. By default Next.js does not optimize SVG images; apps that setimages.dangerouslyAllowSVG: trueare the clearest exposure, but the advisory is not limited to that setting, so patch either way. - Server Actions DoS (GHSA-p3m5-59mp-jv5r). Any App Router app with at least one Server Action, on Next.js 13 through 15.5.27 or 16.0.0 through 16.4.0. Pages Router apps and apps without Server Actions are not vulnerable.
Why does npm audit say my app is safe?#
Because the advisory feed it reads may not list these issues yet. On October 17, 2026, I installed next@16.4.0, react and react-dom in an empty project and ran npm audit:
$ npm audit --json | jq .metadata.vulnerabilities
{ "info": 0, "low": 0, "moderate": 0, "high": 0, "critical": 0, "total": 0 }Zero findings on a version with two open critical advisories. Treat npm audit, Dependabot and similar scanners as a backstop here and check the versions yourself, or use the script below.
A script that checks your app against all three advisories#
I wrote this to check every app I run. It reads the installed next version, resolves sharp from Next.js's own folder (the copy the image optimizer actually loads), scans your source for use cache, use server and dangerouslyAllowSVG, and exits with code 1 if anything is unpatched, so you can drop it into CI. It has no dependencies.
// 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)Run it from your project root with node check-next-security.mjs. This is the real output on a Next.js 16.4.0 app with one use cache function and one Server Action, before and after 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.The script checks versions and source patterns; it is not an exploit test. A clean result means you are on patched versions, which is what the advisories ask for.
How do you upgrade Next.js 16 to the patched version?#
Install the latest 16.4 patch, then confirm sharp moved with it. Next.js 16.4.1 raised its sharp requirement to ^0.35.5 (16.4.0 accepted ^0.35.4; I read both from the npm registry), so npm has to upgrade sharp when you upgrade next.
npm install next@16.4.2
npm ls next sharpIn my test, a project whose lockfile held next@16.4.0 and sharp@0.35.4 came out of npm install next@16.4.1 with sharp@0.35.5, as expected. Run the same check with pnpm why sharp or yarn why sharp if you use those package managers.
eslint-config-next should match your next version, so bump it in the same commit. If you have not moved to 16 yet, the version 16 upgrade guide covers the breaking changes; that is a bigger job than this patch, so patch 15.x first.
How do you patch Next.js 15 safely?#
Upgrade to 15.5.28, then check sharp separately, because upgrading next alone may not fix the SVG bug. Next.js 15.5.28 declares sharp as ^0.34.3 || ^0.35.5, so an existing lockfile that already resolved sharp 0.34.x still satisfies it, and npm keeps it.
This is what happened on a real project with next@15.5.27 and sharp@0.34.5 in the lockfile:
$ 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 # fixedIf sharp is a direct dependency in your package.json, run npm install sharp@0.35.5 instead. To force one version across a monorepo, add an override:
{
"overrides": {
"sharp": "0.35.5"
}
}pnpm uses pnpm.overrides and Yarn uses resolutions for the same job.
How do you patch a self-hosted Next.js app in Docker or Coolify?#
Update the lockfile, rebuild the image without reusing old layers, redeploy, then check the versions inside the running container. A dependency fix only protects you once the container that serves traffic contains it, and a Docker build that copies package-lock.json and runs npm ci installs exactly what the lockfile says.

- Update and verify locally.
npm install next@16.4.2,npm ls next sharp, run the checker. - Commit
package-lock.json. Without it, your build server resolves whatever it resolved last time. - Rebuild the image. With the standalone output used in my production Next.js Dockerfile,
next buildcopiessharpand its native libvips package into.next/standalone/node_modules. In my build that was@img/sharp-libvips-linux-x64, the glibc variant. An image built before the patch keeps the oldsharpuntil you rebuild it. - Redeploy. In Coolify, push the commit or click Redeploy. To skip cached layers for this one build, trigger a forced deploy, for example through the Coolify API with
GET /api/v1/deploy?uuid=<app-uuid>&force=true. My self-host Next.js with Coolify guide covers the deploy setup. With plain Docker, rundocker compose build --no-cache && docker compose up -d. - Verify the running container. In a standalone image the app lives in
/app, so:
docker exec <container> node -e "console.log(require('/app/node_modules/next/package.json').version, require('/app/node_modules/sharp/package.json').version)"Requiring the package.json files by absolute path works even though sharp 0.35.5 does not export ./package.json. I checked the same command against a standalone build of Next.js 16.4.2; it printed 0.35.5 16.4.2 for sharp and next. Adjust the path if your Dockerfile copies the app somewhere other than /app.
What if you cannot upgrade Next.js today?#
Only the SVG bug has an interim mitigation; the use cache RCE and the Server Actions DoS have no workaround, so plan the upgrade within hours, not weeks. In the meantime:
I tested the sharp.block call with sharp 0.35.5: before it, a small SVG converted to a 100-byte PNG; after it, the same call failed with 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'] })The sharp advisory adds one hardening note: whether the librsvg bug can reach code execution depends partly on the Node.js binary. It recommends a node built as a Position Independent Executable (PIE), notes that most Linux distribution packages already are, and warns that the official Node.js binaries are not.
How do you know whether you were attacked?#
The advisories publish no indicators of compromise and do not mention exploitation in the wild, so look for the side effects each bug would leave, and re-check the advisories for updates.
- DoS: sustained 100% CPU on a Next.js process together with slow or failed requests, especially
POSTrequests carrying aNext-Actionheader. - SVG RCE: unexpected requests to
/_next/imagewith.svgsources, crashes of the Node.js process during image optimization, and new child processes or outbound connections from the container. - Any RCE: unknown files in the container filesystem, changed environment variables or secrets used from new IPs. If you find any of these, rotate secrets (database URLs, API keys,
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY) after patching.
Security habits that make the next patch faster#
This was an out-of-band release that landed eight days after 16.4.0 shipped on October 6. A few habits keep the next one to a ten-minute job:
- Stay on an LTS line. Security fixes land on 16.4.x (Active LTS) and 15.5.x (Maintenance LTS).
- Turn on upgrade nudges. Next.js 16.4 added
experimental.agentUpgrade, whose default'security'policy reminds you duringnext devandnext buildwhen an upgrade fixes a known vulnerability in your installed version (Next.js 16.4 notes). - Run the checker in CI. Exit code 1 fails the build when a vulnerable version is installed.
- Pin and commit lockfiles, then rebuild images from them so the running version is the one you reviewed.
- Keep Server Actions small and authenticated. The DoS needs only one action to exist, but auth and input validation limit what any future bug can reach; see Server Actions vs Route Handlers.
Common mistakes when patching#
Related: I packaged the checker script above as a reusable agent skill, so Claude Code, Cursor, Codex or Copilot can run the check and patch for you. See Agent Skills: how to write a SKILL.md.
Key takeaways#
- The October 14, 2026 update fixes two critical RCEs (
use cachetyped arrays and SVG viasharp) and a high-severity Server Actions DoS. - Patched versions are Next.js 16.4.1+ and 15.5.28+, with
sharp0.35.5 or later. - On 15.x, upgrading
nextcan leavesharp0.34.x installed; runnpm update sharpand verify. npm auditreported nothing for unpatchednext@16.4.0on October 17, 2026, so check versions directly.- A self-hosted fix only counts after you rebuild the image, redeploy and verify the versions inside the running container.
Questions
Share


