On 25 October 2026 I ran an audit across the seven Next.js sites I host myself, and six of them were vulnerable. The portfolio you are reading sat on 16.2.10. The cause was a Next.js vulnerability batch that the team shipped as an out-of-band release on 14 October: two critical remote code execution bugs and one denial of service.
Below: which versions are affected, how to check yours in a couple of minutes, what I changed and what I left alone. A security reel is going around Instagram and LinkedIn with 15 IDs on it, and one label in it is wrong. That matters for the fix, so I start there.
Next.js vulnerability of 14 October: what was fixed#
The source is the official Next.js security update of 14 October 2026 and the linked GitHub advisories. The fixed releases are 16.4.1 and 15.5.28. On 25 October the latest on npm is 16.4.3.
| ID | What | Who is affected | Fixed in |
|---|---|---|---|
| GHSA-673q-mjm6-r5xr (no CVE yet), CVSS v4 9.5 | Unauthenticated RCE in use cache functions that return typed arrays | 16.0.0 to 16.4.0, App Router with Cache Components and a use cache function returning several typed arrays | 16.4.1 (15.x is not listed) |
| GHSA-2464-fhr4-w9xw, upstream CVE-2026-96889, CVSS v4 9.5 | Unauthenticated RCE in the Image Optimization API when SVG files are processed | 10.0.0 to 15.5.27 and 16.0.0 to 16.4.0, on glibc Linux | 15.5.28 and 16.4.1 |
| GHSA-p3m5-59mp-jv5r, CVE-2026-94482, CVSS v4 8.2 | Denial of service in App Router with Server Actions | 13.0.0 to 15.5.27 and 16.0.0 to 16.4.0, with at least one Server Action | 15.5.28 and 16.4.1 |
Pages Router apps with no Server Actions are not affected by the third one. The first and third have no workaround. For the first, Vercel recommends upgrading even if you have no such function. That is what I did.
CVE-2026-96889 is not a Next.js CVE#
The reel calls it "Next.js CVE-2026-96889". The record says otherwise: it is a use-after-free in librsvg ("xml includes have duplicated entities"), published on 23 September by Red Hat as CNA, CVSS v3.1 7.8. Next.js picks it up through sharp, which renders SVG with librsvg. The sharp advisory is GHSA-wq5f-xc86-pv6w: versions below 0.35.5 are affected.
Why does the label matter? Because it changes the fix. Upgrading next is one mitigation, and making sure sharp is at 0.35.5 or newer is the other. Here is the catch: next@16.4.3 depends on sharp ^0.35.5, but next@15.5.28 accepts ^0.34.3 || ^0.35.5. On 15.x a lockfile can happily keep sharp 0.34.x after the update. I saw exactly that, so I pin sharp explicitly.
Two more facts before you panic. None of the reel's 15 IDs is in the CISA KEV catalog (checked against the 23 October version), and CISA's ADP assessment lists exploitation as "none" for all of them except this one, which is marked "poc". "Black October" is not a named campaign, just a cluster of real advisories (nginx, Next.js, GitLab, PHP, Node.js, Java) landing in the same fortnight. I cover the rest of the list in the October 2026 CVE roundup.
How to check your Next.js version and exposure#
I don't trust what the browser shows here. Check the lockfile and the running container:
npm ls next sharp # pnpm: pnpm why next
npm view next dist-tags # what is current on npm
npm audit --omit=dev # pnpm: pnpm audit --prod
docker run --rm <image> node -v # Node version inside the imageThen three greps to see which advisory actually applies to you:
grep -rn "use cache" app src # first RCE
grep -rn "use server" app src # Server Actions DoS
grep -n dangerouslyAllowSVG next.config.* # SVG pathNo use cache means the first bug could not reach you, but update anyway. No "use server" means the DoS is off the table. A dangerouslyAllowSVG: true in the config is the one I would look at hardest.
How to fix: Next.js, sharp, zod, Node in Docker#
The fix list, in the order I applied it:
npm install next@16.4.3 # if you are on 16.x
npm install next@15.5.28 # if you are on 15.x
npm install sharp@^0.35.5 # explicit pin- Next.js. 16.x goes to 16.4.3, 15.x to 15.5.28. If you skipped updates in September, remember the earlier advisories: RCE on Windows-hosted servers (CVE-2026-75604, fixed in 15.5.24 and 16.3.3), RCE in Image Optimization with AVIF (same versions), and RCE in
next/ogImageResponse (CVE-2026-94545, fixed in 16.3.6). Jumping straight to the current versions covers all of them. - sharp. Pin
^0.35.5, for the reason above. Earlier sharp advisories (libvips in GHSA-f88m-g3jw-g9cj, libheif in GHSA-rgj7-g3m4-5g8c) are covered by the same pin. - zod. While in the lockfile I moved zod 4.x to 4.6.6 or newer: GHSA-mrhx-c7xc-m3w5 is memory exhaustion on oversized constrained collections.
- Node in Docker. Node.js shipped 22.23.4, 24.22.1 and 26.12.1 on 21 October (official post), with four highs: a Brotli decoder out-of-bounds write,
dns.resolve*truncating names at a NUL character, and two TLS hostname check bypasses. A running container does not update itself. The image has to be rebuilt. - SVG. If nothing in your app passes SVG through
next/image, setimages.dangerouslyAllowSVGback tofalse.
The Docker part bit me twice. The portfolio's base image was pinned by digest to an old node:22 build. A pin freezes everything, security patches included, and I had no process for rotating it. Another site still ran node:20, which has been end-of-life since April 2026 and gets no fixes at all. A floating node:22-slim is no safer: it can come from the build host's cache, so a rebuild may not pull the new patch. The reliable form is an explicit tag from the AWS mirror:
FROM public.ecr.aws/docker/library/node:22.23.4-slim AS baseTake the variant (slim, alpine) you already use. After the build, docker run --rm <image> node -v must print v22.23.4. If you run Docker yourself, the same logic applies to anything you self-host, which I touched on in the ClewWiki self-hosting write-up.
What I found on my seven sites#
My setup: seven Next.js sites in Docker on one server, deployed through Dokploy with Traefik in front. There is no nginx, PHP, Java or GitLab on that server, so most of the October list did not concern me.
| Check | Result on 25 October |
|---|---|
| Vulnerable on audit | 6 of 7 |
| Versions found | 16.2.10 (portfolio), 16.3.8, 15.5.21, 15.5.22, 15.5.23, 15.5.25; one already on 15.5.28 |
npm audit --omit=dev on the portfolio | 12 issues: 2 critical (next, dompurify), 8 high. After the update: 0 critical |
use cache in code | none of the 7 sites |
| Server Actions | one site, so the DoS applied there |
| Docker base images | one digest-pinned to old node:22, one on node:20; all moved to node:22.23.4-* |
The finding I like least is in the portfolio's next.config.js. It had images.dangerouslyAllowSVG: true behind a sandbox CSP, and in the whole project not one SVG had ever gone through next/image. It was an open path to exactly the SVG bug, with zero benefit. I turned it off.
What remains#
After the update, the remaining highs in npm audit are build-time only: the workbox and next-pwa chain, and postcss inside next. They run only while the Docker image is being built, not in the server process, so an attacker has no route to them at runtime. I left them for the next dependency cycle and I am saying so rather than claiming a clean report. One more honest gap: the portfolio itself is on zod 3, and the zod fix exists only in 4.6.6. Its two schemas validate short strings with a length cap, not collections, so the memory bug has nothing to grow on there; the move to zod 4 goes on the list. The RCE paths from this batch are closed on all seven.
I also did not touch things outside my stack. Nginx 1.30.6 or 1.31.7, PHP 8.5.12 and its siblings, GitLab and Java have their own fixes, and the roundup linked above has the details.
Checklist#
npm ls next sharpshows next 16.4.1+ (16.4.3 current) or 15.5.28, and sharp 0.35.5 or newer.npm audit --omit=devhas no criticals.dangerouslyAllowSVGis off unless you really serve SVG throughnext/image.- zod is 4.6.6 or newer.
- Dockerfile uses an explicit
node:22.23.4-*tag, not a stale digest and notnode:20. - The image was rebuilt, and
node -vinside it matches. - After deploy, the new build is actually the one serving traffic, not a cached one.
If you only have ten minutes, do items 1, 3 and 5. They cover the two critical RCEs and the one patch my own pin had frozen.



