← All posts
·7 min read

Node.js security update: what to check first

A Node.js security release is an inventory problem first. Find the version your laptop, CI and host really run, then which October 2026 fixes matter.

On 21 October 2026, Node.js shipped security releases for all three supported lines: 22.23.4, 24.22.1 and 26.12.1. Together they fix ten vulnerabilities, four of them rated High (Node.js advisory). PHP shipped emergency fixes the same day for two critical flaws nicknamed PHP2Shell (php.net). Two runtimes, one patch day.

For anyone running Node in production, the first question isn't "how bad is it?" It's "which Node am I actually running?" For most teams that question has more than one answer. Checking this site against the release gave three.

This post is for the engineer or tech lead who runs a Node app in production (a Next.js site, an API, a background worker) and wants to know what to do this week.

Three environments, three answers

There is no single "our Node version". Each place your code runs picks one in its own way:

Where it runsHow the version is chosenWhat this site had
LaptopWhatever was installed last26.7.0, older than the 26.12.1 fix
CI (GitHub Actions)node-version: 22 in each workflowThe newest 22.x the runner has, which may lag
Host (Vercel)Major version in project settings, overridden by engines in package.json"node": ">=22", which Vercel reads as the latest 24.x
Each environment picks its Node version somewhere different, and gets the patch on a different schedule.

The laptop is the one everyone checks first and the one that matters least. Nothing on a laptop serves real users.

CI is the quiet surprise. A version spec like 22 reads as "latest 22", but setup-node first looks for a match in the runner's local cache and only downloads if it finds nothing. So on patch day your build can keep running the older 22.x until the runner image is refreshed. Setting check-latest: true makes it ask for the newest release that matches.

The host is the one that matters most. On Vercel you pick only a major version (22.x or 24.x today), and Vercel's docs say it "automatically rolls out minor and patch updates" for security fixes. An engines field in package.json overrides the dashboard. This site's said "node": ">=22", and the same docs map a range like that to the latest 24.x. So the floor that read as "Node 22" deployed Node 24, while CI tested on 22.

Both lines got the fix, so that isn't dangerous on its own. But the version you tested isn't the version you serve, and the fix to confirm is 24.22.1, not 22.23.4. The docs give the check: log process.version from a function after redeploying, instead of trusting the default.

I've since pinned this site to "24.x" and moved CI to Node 24 with check-latest: true. That's the checklist at the end of this post, applied to itself.

Which of the ten fixes matter for your app

Don't triage by severity score alone. Triage by what your code actually does. For a typical Next.js or API backend that spends its day calling other services (model APIs, CRMs, webhooks), the four High-severity fixes sort like this:

  • TLS hostname checks (CVE-2026-105483, CVE-2026-106069). TLS is what proves an HTTPS server is the one you meant to reach. Both bugs let that check be bypassed when the host is written as an unusual form of IP address. They matter most where your code connects to a host it didn't choose: a URL from user input, a webhook address a customer configures, an agent fetching a page a model picked.
  • Brotli decoding (CVE-2026-111497). Brotli is a compression format. The bug is an out-of-bounds write that the advisory says permits remote code execution. Node's built-in fetch decodes Brotli responses for you, so the exposure is any response from a server you don't control, not just code that calls zlib directly.
  • dns.resolve and NUL characters (CVE-2026-105482). Names containing a NUL character get cut short. This matters if you resolve a hostname to check it against an allowlist before letting code connect.

The other six are narrower. Most only apply if you build startup snapshots or single executable apps, or use Node's permission model, which most web apps never do.

If your app makes outbound calls to hosts that users or models influence, treat this release as urgent. That's the same "is it reachable?" question I asked about the Next.js AVIF fix in August, and the answer to it decides your priority, not whether you patch. Agents make the reachability question worse, because the host they connect to is often chosen by model output. The same "untrusted input decides the action" problem is behind prompt injection.

PHP2Shell is the same lesson in a different runtime

PHP's two critical flaws (CVE-2026-109618 and CVE-2026-109619, scored 9.2) are fixed in 8.5.12, 8.4.27, 8.3.36 and 8.2.35. php.net says the risk is highest for mod_php, PHP running inside the Apache web server, and that updating is the only safe choice. BleepingComputer reports Cloudflare seeing early exploit attempts before the patches shipped.

How exposed you are depends on how the runtime is deployed, not just which version it is. That's the Node lesson again.

Make the version something you can review

Patching is easy once you know what to patch. The lasting fix is making the version visible:

  1. Write the host's major into the repo, exactly. Use "node": "24.x" in engines, not a floor like >=22. A floor quietly moves to the next major whenever your host adds one. An exact major changes only in a commit someone reviews.
  2. Make CI test the major you serve, and its newest patch. Set node-version to the same major as engines, and add check-latest: true (or pin the exact patch and bump it on purpose).
  3. Log process.version at startup. It costs one line, and on the next patch day the answer is already in your logs.
  4. Update your laptop last. It's still worth doing, but it's the environment with the lowest stakes.

The patch itself takes minutes. Finding out which of your environments needed it is the part that takes the afternoon, and you can do that ahead of the next patch day. Keeping production apps patched and boring to run is part of the full-stack work I take on.

Shanker Dhand
Shanker Dhand
AI Engineer & Technical Lead

I design and ship production AI systems — RAG pipelines, agents, and evaluation infrastructure — built on 10+ years of full-stack engineering.

Related posts