- CVE-2026-111497 is an out-of-bounds write in the Brotli decoder bundled with Node.js, fixed on 21 October in 22.23.4, 24.22.1 and 26.12.1. An attacker who can supply Brotli data your application decompresses "can corrupt process memory, which can lead to a crash, disclosure of process memory, or remote code execution".
- The researchers reached code execution "against the official vulnerable Node.js build", on the official 24.22.0 Linux arm64 image, and were candid that "execution took multiple attempts in our setup".
- Lambda patches managed runtimes for you, on its own schedule, and not at all if a function is pinned to Manual mode. For a function deployed as a container image, "you're responsible for rebuilding your function's container image from the latest base image and redeploying".
- Node 20 reached End-of-Life on 30 April 2026 and gets no fix. The
nodejs20.xLambda runtime was deprecated the same month, after which AWS "may no longer apply security patches or updates to that runtime".
Node.js shipped ten CVEs on 21 October. One of them decides your week: CVE-2026-111497, which the researchers who demonstrated it call Node2Shell, an out-of-bounds write in the Brotli decoder bundled with every supported Node release line.
The patch is three version numbers and a deploy. The hard part is that Node is not one thing on your estate: a package on some instances, a managed runtime on some Lambda functions, a layer inside thirty images, a binary on every build agent. Only the first gets fixed by patching a host.
So the first hour goes on counting rather than patching. We got that order wrong on a Java release once and spent a fortnight afterwards finding images nobody had on a list.
What does Node2Shell actually break?
The decompressor, before your application sees anything. The Node.js advisory of 21 October says an attacker who can supply Brotli data that an application decompresses with node:zlib "can corrupt process memory, which can lead to a crash, disclosure of process memory, or remote code execution". The flaw is an invalid block switch read as a request for more input, so the streaming decoder keeps appending bytes to "an eight-byte internal buffer".
It is rated high, and not a thought experiment. The Imperva Red Team, who named it, reached remote code execution "against the official vulnerable Node.js build", on the official 24.22.0 Linux arm64 image. They also say plainly that "execution took multiple attempts in our setup". Multiple attempts against an endpoint answering a thousand requests a minute is not a defence.
The bug is not Node's own code. Google's Brotli project published 1.0.10, 1.1.1 and 1.2.1 the same evening, so anything else on your estate linking the decoder has a patch of its own to find.
Which of your services decompress Brotli from a stranger?
Fewer than you fear, more than anyone can name from memory. Imperva tested two ordinary routes: Node's built-in fetch() reading a Brotli-compressed response, and Express 5.0.0 to 5.3.0 with body-parser 2.0.0 to 2.3.0 decoding a Brotli-compressed request body. The outbound one is the route teams discount, because a call is an act of trust in whoever answers it. Three places to look:
- Ingest handlers accepting
Content-Encoding: br. - Outbound HTTP from Node to anything you do not operate.
- Batch jobs decompressing objects a customer uploaded.
Where is Node actually running in your AWS accounts?
In more places than the diagram shows, which is the problem the PHP release handed everyone three days earlier. The post on PHP2Shell put inventory ahead of patching for the same reason: the host that gets taken was never on the list.
Node makes it worse, because Node is also a tool:
- EC2 and Elastic Beanstalk, where a package manager owns the version.
- Lambda managed runtimes, where AWS owns it, with conditions.
- Container images on ECS, EKS and Lambda, where nothing changes until you rebuild.
- Node that is not your application: build agents, CDK deploys, an
npxstep in CI.
That last group carries no customer traffic and all of your deploy credentials. A build agent resolving packages consumes responses from the internet, which is the shape of the poisoned LiteLLM release: the question was what the pipeline could reach.
Why is patching the host the smaller half of the job?
Because an image is a frozen filesystem and your package manager has no opinion about it. A host updated this morning runs a node:24-alpine layer built in August, and the process serving traffic is the one in the layer.
Lambda divides on the same line. AWS's shared responsibility table for runtimes commits to "apply runtime updates automatically by default" for managed runtimes. For container images it hands the job back: "Regularly re-build and re-deploy your container image using the latest base image."
Two details decide whether your managed runtimes are covered. The first is the rollout. Lambda's runtime update documentation describes two phases: a new version arrives "whenever you create or update a function", and only then does Lambda sweep up the untouched ones. Deploy on Monday and you are patched on Monday. The function that last shipped in March is patched when Lambda gets to it, and you cannot look up the date.
The second is a setting a compliance programme probably talked someone into. Of the three update modes, "Functions using Manual mode don't receive runtime updates". Manual pins a runtime version ARN: good for reproducibility, and a very quiet way to sit on an unpatched decoder for a quarter. AWS's own advice for "strict patching freshness requirements" is to deny PutRuntimeManagementConfig with a service control policy so every function falls back to Auto.
Nobody will tell you, either. As of this morning there is no entry for this release in the AWS security bulletins, where PHP got one within days. Go and look.
What do you do about Node 20 and older?
Move, and put a name and a date on it this week. The advisory is one sentence: "End-of-Life versions are always affected when a security release occurs." The release schedule has Node 20 at End-of-Life since 30 April 2026, so no 20.x carries this fix.
AWS followed the same calendar. nodejs20.x was deprecated that month, after which AWS "may no longer apply security patches or updates to that runtime". Those functions still run and nothing in the console goes red.
Check where you are landing. Node 22 is Maintenance LTS until April 2027 and Node 24 is Active LTS until April 2028, so 22.23.4 buys eighteen months and 24.22.1 buys two and a half years. Same regression testing either way, so do it once.
Do the TLS fixes matter if you call internal services by IP?
A great deal, and they are the half of this release nobody is writing about. Read CVE-2026-106069 if a service of yours connects to an address rather than a name. With a leading-zero IPv4 literal, tls.checkServerIdentity() normalises the host by WHATWG URL rules, "which read a leading-zero octet as octal", while the connection goes through the operating system resolver, which "on some platforms such as macOS reads it as decimal". The certificate is checked against one address and the socket opened to another.
Then DNS. CVE-2026-105482 lets a hostname containing a NUL byte be silently truncated, so an application validating a name "against a domain allowlist" and then resolving it with dns.resolve*() can act on records for a different one. If you wrote that allowlist, this is your code.
The release also ships a CA bundle dropping the compromised eMudhra intermediates, whose private keys were recovered because "the 8 impacted keys all used integers less than 256". An Indian certificate authority, revoked last week, trusted by your Node processes until you upgrade.
What do the RBI directions expect of a patch like this?
A mechanism, and a plan for the versions that can never have one. The RBI directions of 31 July 2026 require at paragraph 58 that where a patch is released "to mitigate critical vulnerabilities that are actively exploited or widely reported, the bank shall have a mechanism to deploy such patches expeditiously".
Only one limb of that is satisfied here. Nobody has published evidence of Node2Shell being exploited in the wild, unlike the PHP case where Amazon found an attempt before disclosure. "Widely reported" covers it anyway, and what gets examined afterwards is the mechanism.
Paragraphs 37 and 38 bite in a year. The bank "shall avoid using outdated and unsupported hardware or software" and "shall develop a technology refresh plan". Node 20 in production is that paragraph written down in advance, and the rest of the directions are in our post on them. If you find a worker you think was reached, start with what its role could touch, the arithmetic we walked through for an instance role leaving the box.
What can you run on Monday?
Two jobs, about ninety minutes. Lambda first, because that answer is an API call:
aws lambda list-functions \
--query 'Functions[].[FunctionName,PackageType,Runtime]' \
--output text
Anything showing Image and no runtime is yours to rebuild. For the rest, ask each function whether it is actually taking updates:
aws lambda get-runtime-management-config \
--function-name NAME \
--query '[UpdateRuntimeOn,RuntimeVersionArn]' --output text
Manual is the finding. Auto means you are waiting on a rollout with no published date, and FunctionUpdate means you are waiting on a deploy, so the fastest safe fix is to deploy it today.
Then the images, asking the running digest rather than the Dockerfile:
docker run --rm --entrypoint node IMAGE@sha256:DIGEST \
-p process.versions.node
grep -rInE 'brotliDecompress|createBrotliDecompress|content-encoding[^a-z]{0,8}br' \
--include='*.js' --include='*.mjs' --include='*.ts' .
When is the proxy rule enough?
For the hours between finding a service and redeploying it, and no longer. Stripping Content-Encoding: br at CloudFront or an ALB closes the inbound route and does nothing about the outbound one, which Imperva demonstrated first. A service calling a third-party API still decompresses whatever that API returns.
There is also an honest case for waiting. A Node 24 service behind a mutual-TLS gateway, consuming Brotli from nobody, with no internet egress, can go on the next release train. We have watched a team patch the loudest item and leave eleven images untouched for a month. Every action was correct, the order was wrong.
The short version
- Upgrade to 22.23.4, 24.22.1 or 26.12.1, treating the Brotli fix, the TLS hostname fixes and the new CA bundle as one deploy.
- Inventory by where Node lives: the package manager on EC2 and Beanstalk,
get-runtime-management-configfor Lambda, the running digest for every image, build agents last. - Rebuild and redeploy every container image yourself. Nothing on AWS does it for you.
- Node 20 and older get no fix, and
nodejs20.xhas been deprecated since April, so name an owner and a date now.
Before any of that, open your task definitions and your function list and count the distinct Node versions you run. If that number surprises anyone in the room, the count is the finding and the patch was always the easy part.
This is engineering guidance, not legal advice. Regulations and their annexures are amended over time; read the current text and take your compliance position from counsel.
We are a DevSecOps company in Kochi, working with fintech, crypto and AI teams across India, the UAE, the US and the UK. Infrastructure we build and run has secured over $3B in transaction volume at 99.9% uptime, for clients including BILLDESK and Coinshift and for teams backed by Y Combinator and Sequoia.
The work is built to survive an audit rather than to describe one: SOC 2 Type II, ISO 27001, PCI DSS and SLSA 3. Our VAPT team holds OSWE certification, has spoken at Defcon, BlackHat and OWASP, and has found critical CVEs in open source software.
We rank ourselves first in our guide to choosing a DevOps company for a fintech — and we say so on that page, in the second paragraph, rather than presenting it as a neutral list. Read the criteria there and hold us to them.
Find out how many Node versions you are actually running
The free cloud security audit covers the runtime inventory: every Node version across your accounts and regions, which Lambda functions are pinned to Manual runtime updates, which container images carry a runtime nobody rebuilds, where Brotli reaches a decoder from outside your network, and what a compromised worker's role could have touched.
Book the free audit PHP2Shell on AWS: Which of Your PHP Versions Are Still Exposed?