What was published on October 14
On October 14, 2026, the Next.js team published an out-of-band security update: version 16.4.1 for the Active LTS line and version 15.5.28 for the Maintenance LTS line. It fixes three flaws tied to upstream dependencies: two critical, unauthenticated remote code executions and one high-severity denial of service. Two of these fixes had been postponed from the September release because of upstream delays.
On a server you administer, the fix does not arrive on its own. You must raise next, check that the sharp library follows, rebuild the application and restart the process that actually serves traffic. This article walks that path for PM2, Docker and Coolify, without redoing a Next.js server installation.
Key points
- GHSA-673q-mjm6-r5xr (critical) — unauthenticated remote code execution in an App Router application with Cache Components, when a
use cachefunction returns several typed arrays. No known workaround. The advisory gives the range 16.0.0 to 16.4.0 and a CVSS score of 9.5. - CVE-2026-96889 / GHSA-2464-fhr4-w9xw (critical) — remote code execution through an upstream library of the image optimization API, when SVG files are used, on glibc-based Linux. Score of 9.5. Official workaround: sharp 0.35.5 or later.
- GHSA-p3m5-59mp-jv5r (high) — denial of service in an App Router application with at least one Server Action: crafted requests saturate the CPU and block later requests in the same process. Score of 8.2. The Pages Router, or an app without Server Actions, is not affected.
- Fixed versions — 16.4.1 for the 16 line and 15.5.28 for the 15 line, with the official commands
npm install [email protected]andnpm install [email protected]. - No CVE for two advisories out of three — only the image RCE carries a CVE identifier. The other two are tracked by their GHSA identifier: a tool that only looks for CVEs will miss them.
- Even without direct use — for the
use cacheRCE, Vercel asks you to update even if your application has no similar function.
Without use cache or SVG, why that is not enough
Three reasons not to stop at that objection. First, for the use cache RCE the announcement is explicit: no workaround exists, and the update is requested even when the application has no similar function. Second, the image RCE depends on an upstream library, and you do not always know which SVG files reach the optimizer, especially when images come from remote sources. Third, the denial of service needs only one Server Action, which many App Router forms already contain.
The risk of breakage is limited: the upgrade stays within the same line, 16.4.x or 15.5.x. One constraint to know: version 16.4.1 declares Node 20.9 or later, while 15.5.28 accepts Node 18.18 and above. If you run an older 16.x, moving to 16.4.1 stays within the same major version.
Which version to install for your line
Scroll the table
| Your version | Status | What to do |
|---|---|---|
| 16.0.0 to 16.4.0 | Affected by all three advisories | Move to 16.4.1 or to a newer 16.4.x |
| 16.4.1 and later | Fix included | Check sharp and the real redeploy |
| 15.0.0 to 15.5.27 | Affected by the image RCE and the DoS | Move to 15.5.28, then plan the migration to 16.4.x |
| 15.5.28 | Fix included | Plan the migration to 16.4.x |
| 13.x and 14.x | Affected, no fix published for these lines | Migrate to 15.5.28 or 16.4.1 |
| 10.0.0 to 12.x | Affected by the image RCE, no fix published | Migrate to a maintained line |
Find out what is really running
The version written in your repository is not the one answering requests. A lockfile may predate the fix, a Docker build may reuse a cached layer, a PM2 process may point to an old release directory. With the standalone output, Next.js copies the files it needs from node_modules into the deployment folder: the bundled sharp is therefore the one present at build time, not the one you installed afterwards. The following checks run on the machine or in the container that serves traffic.
Take inventory in five checks
Read the Next.js and sharp versions
From the project root:
npm ls next sharp, orpnpm why sharpwith pnpm. For the exact Next.js version:node -p "require('next/package.json').version". Asharpbelow 0.35.5 undernextneeds fixing.Spot Cache Components and use cache
grep -rn "cacheComponents" next.config.*thengrep -rln "use cache" app src. IfcacheComponentsdoes not appear, your application does not take the path described in the advisory. Update anyway: Vercel asks for it in every case.Spot SVG usage
grep -rn "dangerouslyAllowSVG\|remotePatterns" next.config.*andfind public -name "*.svg". By default, the documentation says Next.js does not optimize SVG images, and thatdangerouslyAllowSVGallows them. A missing setting is a good sign, not proof: the advisory does not detail the exact path.Spot Server Actions
grep -rln "use server" app src. A single file is enough to make an App Router application subject to the denial of service.Identify the system C library
ldd --versionprints GNU libc on Debian, Ubuntu, AlmaLinux or Rocky, and musl libc on Alpine. The advisory only mentions glibc and says nothing about musl: do not conclude that Alpine is spared. In a container:docker exec <container> ldd --version.
Update, then check the lockfile
Run the command for your line: npm install [email protected] or npm install [email protected]. One trap remains that the announcement does not detail. Version 16.4.1 declares sharp as an optional dependency with the range ^0.35.5, but 15.5.28 declares ^0.34.3 || ^0.35.5. A lockfile that already holds a 0.34.x satisfies that range: the package manager has no reason to raise it.
So check the result with npm ls sharp. If it shows a version below 0.35.5, force the upgrade with npm install sharp@^0.35.5, or add an override in package.json, for example "overrides": { "sharp": "^0.35.5" }. With pnpm or yarn, the equivalent is to raise sharp or declare an override. Commit the lockfile: it is what your CI and your Docker image will read.
Redeploy for your target
Validate the build
npm ci, thennpm run build, thennpm ls next sharp. If the build fails on Node, check the version required by the line you chose.PM2
Build in the directory PM2 runs, then
pm2 reload <name>. Then check withpm2 describe <name>that the execution directory is the one you just rebuilt: with a releases layout, a forgotten symlink restarts the old code.Docker
Rebuild without cache:
docker build --no-cache -t myapp:fixed ., or at least invalidate thenpm cilayer. Restart withdocker compose up -d --force-recreate. Then compare the running container image (docker inspect -f '{{.Image}}' <container>) with the one you just built.Coolify
Trigger a redeploy that ignores the build cache, then read the log: the dependency installation step must run, not be marked as reused. A simple restart rebuilds nothing.
Prove the fix
Read the version in the running process, not in the repository:
docker exec <container> node -p "require('next/package.json').version"must print 16.4.1 or 15.5.28 (or a newer version of the same line). Checksharpwithdocker exec <container> grep '"version"' node_modules/sharp/package.json, which must show 0.35.5 or later.
If you cannot redeploy today
For the use cache RCE there is no workaround: only the update fixes it. For the other two flaws, a few mitigations reduce the risk in the meantime. They do not replace the fix, and you should record them as temporary in your operations log.
Temporary mitigations, not fixes
- Raise sharp alone — this is the official workaround for the image RCE: sharp 0.35.5 or later. Check that the build passes and that image optimization still works.
- Do not serve SVG through the optimizer — leave
dangerouslyAllowSVGdisabled and do not enable it without a proven need. - Restrict
images.remotePatterns— limit the remote sources the optimizer accepts to hosts you control. - Node as a PIE executable — the sharp advisory cites this mode to reduce the risk of code execution, noting that official Node.js binaries are not PIE.
- Reduce possible damage — a process without root rights, a read-only container (
docker run --read-only), no unnecessary secrets in the environment. - Rate-limit in front of Next.js — a
limit_reqrule in nginx and a CPU alert slow down a denial of service without preventing it.
Run npm audit after updating
npm audit relies on the GitHub advisory database: it therefore covers GHSA identifiers, including those with no CVE. Run it after the version bump, and add it to your CI so that the next advisory does not depend on manual monitoring.
After the fix: monitor and plan for the 15 line
The advisories publish no indicator of compromise, so there is no precise signature to search for. Watch for general signs. A Node process whose CPU stays saturated points to the denial of service. Unexpected restarts, child processes the application never starts, or outbound connections from the application user warrant an investigation. In nginx logs, grep "_next/image" access.log | grep -i svg shows optimization requests that target SVG files.
On the 15 line, be careful with the calendar. According to endoflife.date, security support for the 15 line ended on October 21, 2026, while the Next.js policy page gives no date and sets two years of Maintenance LTS. 15.5.28 may therefore be the last fix of that line: plan the migration to 16.4.x. Version 16.4.2, published the day after 16.4.1, contains according to its notes only backports unrelated to these advisories.
Official documentation
Next.js announcement of October 14, 2026: https://nextjs.org/blog/nextjs-security-update-october-14-2026
GitHub advisories: https://github.com/vercel/next.js/security/advisories/GHSA-673q-mjm6-r5xr, https://github.com/vercel/next.js/security/advisories/GHSA-2464-fhr4-w9xw and https://github.com/vercel/next.js/security/advisories/GHSA-p3m5-59mp-jv5r
sharp advisory: https://github.com/lovell/sharp/security/advisories/GHSA-wq5f-xc86-pv6w
Netlify note: https://www.netlify.com/changelog/2026-10-14-nextjs-react-security-vulnerabilities/
Support policy: https://nextjs.org/support-policy and https://endoflife.date/nextjs