Next.js and Node.js security updates: what to upgrade this week (October 2026)
The short version. If you self-host a Next.js app, upgrade Next.js to 16.4.2 (or 15.5.28) and make sure it uses sharp 0.35.5, then redeploy. Two of the bugs fixed this month let an attacker run code on your server without logging in. Separately, Node.js fixed ten vulnerabilities on 21 October, but Node.js 20 is no longer supported and got no fix, so servers on Node.js 20 need to move to Node.js 24. The script below does that on all your servers at once.
This week also brought PHP2Shell, two critical bugs in PHP itself. If any of your servers run PHP, read PHP2Shell: how to patch PHP on your servers first: unlike these, it is already being exploited.
What happened
Next.js: two critical remote code execution bugs
On 14 October Vercel released Next.js 16.4.1 and 15.5.28 to fix three vulnerabilities:
- CVE-2026-96889 (critical): code execution through the image optimizer. Next.js resizes images at
/_next/imagewith thesharplibrary. A bug in the image decoder underneath sharp lets a crafted image run code when Next.js runs on glibc-based Linux, which includes Ubuntu, the system Devpilot sets up. The fix is sharp 0.35.5. - GHSA-673q-mjm6-r5xr (critical): code execution in
use cachefunctions that return typed arrays, in Next.js 16 apps using Cache Components. - GHSA-p3m5-59mp-jv5r (high): denial of service through crafted requests to apps that use Server Actions.
No attacks had been reported when the fixes came out. The image optimizer is a well-known target, though: on one of our own staging sites we found automated scanners asking /_next/image to fetch cloud metadata addresses, the usual first step in stealing a server’s cloud credentials.
Node.js: ten vulnerabilities, and no fix for Node.js 20
On 21 October Node.js released 22.23.4, 24.22.1 and 26.12.1, fixing ten vulnerabilities, four of them rated high:
- CVE-2026-111497: an out-of-bounds write in the Brotli decoder that can lead to code execution when an app decompresses Brotli data from an untrusted source.
- CVE-2026-105483 and CVE-2026-106069: ways to get past the TLS hostname check when your app connects to other servers over HTTPS.
- CVE-2026-105482:
dns.resolvecuts off hostnames at a NUL character.
The release also updates OpenSSL, c-ares, Undici and the bundled CA certificates. No attacks had been reported at the time of writing.
Node.js 20 reached end of life in April 2026 and got no fix, and neither did Node.js 18. The Node.js project’s advice is to move to a supported version.
Are you affected?
Your Next.js apps
You’re affected if you run a Next.js app on your own server (with next start, as apps deployed with Devpilot do) on any version below 16.4.1 on Next.js 16, or below 15.5.28 on Next.js 15. The fixes shipped only for Next.js 15 and 16, so apps on Next.js 14 or older need to move to one of them.
In your project, run:
npm ls next sharp
You need next@16.4.1 or later (we recommend 16.4.2, the current release), or next@15.5.28, and every sharp in the tree at 0.35.5 or later.
Then check how open your image optimizer is. Look at images.remotePatterns in next.config.*. A pattern like { protocol: 'https', hostname: '**' } lets anyone make your server download and decode an image of their choosing, which is the easiest way to reach the sharp bug. You can test a live site from your laptop:
curl -s -o /dev/null -w '%{http_code}\n' \
'https://your-site.com/_next/image?url=https%3A%2F%2Fgithub.githubassets.com%2Ffavicons%2Ffavicon.png&w=64&q=75'
200 means your site will fetch and resize images from any website. 400 means it only accepts the hosts you listed.
Your servers’ Node.js
Open the server in Devpilot, go to Terminal, and run node --version. You need v24.22.1 or later on Node.js 24, or v22.23.4 or later on Node.js 22. Anything on v20 or older needs to move to Node.js 24.
How to fix your Next.js apps
- Upgrade Next.js in your project and commit the lockfile:
npm install next@16.4.2 eslint-config-next@16.4.2 # Next.js 16
Leave out eslint-config-next if your project doesn’t use it. Next.js 16.4.2 requires sharp 0.35.5, so sharp is fixed along with it.
- On Next.js 15, install
next@15.5.28. It still accepts the old sharp 0.34, so force the fixed version by adding this topackage.jsonand runningnpm installagain:
"overrides": { "sharp": "0.35.5" }
- Tighten
remotePatternswhile you’re innext.config.*. List the exact hosts your images come from, such as your own API or storage bucket, instead of**. - Push the change. Devpilot builds and deploys it like any other release. Afterwards, check on the server that the app really restarted: in Terminal,
pm2 listshould show the app’s uptime starting from the deploy. If it doesn’t, the old version is still running from memory, so restart it withpm2 restart <app-name>.
If next build fails after the upgrade with type errors in test files: in our own upgrade, Next.js 16.4 started type-checking test and end-to-end files that 16.1 had skipped. If your tests are type-checked separately anyway, give the build its own config that leaves them out. Add a tsconfig.build.json:
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "e2e", "**/__tests__/**", "**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx"]
}
and point Next.js at it with typescript: { tsconfigPath: "tsconfig.build.json" } in next.config.ts.
A word on supply chain. After a big security release, look-alike and booby-trapped npm packages show up quickly. Install the exact versions above, from the official next and sharp packages, and look over your lockfile changes before you commit them. npm audit signatures confirms that every installed package carries a valid registry signature.
How to update Node.js on a Devpilot server
Devpilot’s App Store installs Node.js from NodeSource’s package repository. The script below upgrades it on each server: Node.js 22 and 24 move to their fixed releases, and Node.js 20 or older moves to Node.js 24. It then restarts PM2, which runs your Node apps, so they pick up the new Node.js.
Every server at once (recommended)
- Open any server in Devpilot, go to Scripts, create a new script, paste in the script below and save it.
- From the script’s menu, choose Run on Multiple Servers, select every server that runs Node.js, and run it.
- Read each server’s output. The last line should start with
OK.
#!/bin/bash
# Node.js October 2026 security release: move Node.js installed from NodeSource to
# a fixed release (22.23.4 or 24.22.1) and restart PM2 on it. Node.js 20 and older
# get no fix, so they move to Node.js 24. Safe to run more than once.
if [ -d /www/server/nodejs ]; then
echo "NOTE: aaPanel Node.js found in /www/server/nodejs. apt can't update it; update it in aaPanel."
fi
if ! command -v node > /dev/null; then
echo "$(hostname): Node.js is not installed. Nothing to do."
exit 0
fi
before=$(node --version | sed 's/^v//')
major=${before%%.*}
LIST=$(grep -ls 'deb.nodesource.com/node_' /etc/apt/sources.list.d/* | head -n 1)
if [ -z "$LIST" ]; then
echo "!! $(hostname): Node.js $before was not installed from NodeSource. Update it the way it was installed."
exit 1
fi
case "$major" in
22|24) target=$major ;;
*) target=24 ;; # 20 and older no longer get security fixes
esac
if [ "$target" != "$major" ]; then
echo "Moving Node.js $before to Node.js $target: Node.js $major no longer gets security fixes."
sudo sed -i -E "s#deb\.nodesource\.com/node_[0-9]+\.x#deb.nodesource.com/node_${target}.x#" "$LIST"
fi
LOG=$(mktemp)
if ! { sudo apt-get update -qq &&
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq nodejs; } > "$LOG" 2>&1; then
echo "apt failed:"; tail -n 20 "$LOG"; rm -f "$LOG"; exit 1
fi
rm -f "$LOG"
after=$(node --version | sed 's/^v//')
echo "Node.js: $before -> $after"
# PM2 keeps running on the old Node.js until it is restarted. `pm2 update`
# restarts PM2 and every app it manages on the new version.
for user in $(ps -eo user:32,args | awk '/PM2 v[0-9.]+: God Daemon/ {print $1}' | sort -u); do
echo "Restarting PM2 for $user"
sudo -u "$user" -H pm2 update > /dev/null 2>&1 || echo "!! pm2 update failed for $user: run 'pm2 update' as $user"
done
if [ "${after%%.*}" != "$major" ]; then
echo "NOTE: Node.js changed from $major to ${after%%.*}. Redeploy each Node.js app on this server so its packages are rebuilt for the new version."
fi
case "${after%%.*}" in
22) fixed=22.23.4 ;;
24) fixed=24.22.1 ;;
*) fixed=999 ;;
esac
if dpkg --compare-versions "$after" ge "$fixed"; then
echo "OK $(hostname) node v$after"
else
echo "!! $(hostname) node v$after is not a fixed release"
exit 1
fi
After moving from Node.js 20
A jump of a whole version, such as 20 to 24, can break packages with compiled parts (for example bcrypt or ssh2) until they are rebuilt. Redeploy each Node.js app on the server afterwards: Devpilot reinstalls its packages, which rebuilds them for the new Node.js, and restarts it. Most current frameworks, including Next.js, NestJS and Express, run on Node.js 24 without changes.
Servers managed by aaPanel
aaPanel installs Node.js under /www/server/nodejs, and apt doesn’t update it. In aaPanel, open the Node version manager, refresh the list, and install 24.22.1 or 22.23.4. Then switch each Node.js project to the new version and restart it. Installing a new version on its own doesn’t move existing projects to it.
What we’ve done at Devpilot
- Our own Next.js sites run Next.js 16.4.2 (or 15.5.28) with sharp 0.35.5, and their image optimizers now accept only our own image hosts.
- Our servers run Node.js 24.22.1.
- The App Store now offers Node.js 24 and 22. Node.js 20 is no longer offered for new installs. Servers that already run it are still detected, but they need the update above.
- Devpilot doesn’t upgrade Node.js on your servers or the packages in your code automatically, so please run the steps above.
- Questions, or not sure whether an app is affected? Email support@devpilot.io.
Sources
- Next.js Security Update for Upstream Vulnerabilities (14 October 2026), Next.js
- GHSA-2464-fhr4-w9xw: image optimizer RCE (CVE-2026-96889), GHSA-673q-mjm6-r5xr and GHSA-p3m5-59mp-jv5r, Next.js on GitHub
- Wednesday, October 21, 2026 Security Releases, Node.js
- Node.js release schedule, Node.js on GitHub

One Comment