On 21 October 2026 Node.js published fixes for ten vulnerabilities. One of them, CVE-2026-111497, was named Node2Shell after a researcher demonstrated code execution through it, and it was reported everywhere as a Node.js flaw.
It is not a Node.js flaw. The CVE is assigned by Google against Brotli, a compression library. Its affected-product list contains exactly one entry — github.com/google/brotli — and nothing else. Node.js bundles that library, so Node users got a fix and a headline. Everyone else who bundles it got neither.
That asymmetry is the whole governance problem, and it is worth examining rather than patching past.
What a product-level inventory cannot answer
Most asset inventories record products: this server runs Node.js 24, that one runs .NET 9, this desktop fleet runs Chrome, that appliance runs a vendor firmware image. Criticality gets assigned, patch cycles get attached, and the document passes an audit.
Now ask the question this CVE asks: which of our systems decode Brotli, and which copy of the decoder do they use?
A product list cannot answer it. The answer, in a typical estate, spans things nobody filed together:
- Node.js, Bun, and anything built on them
- The .NET runtime, whose
BrotliStreamandBrotliDecodersit on a vendored copy - Chromium and Firefox, which decode
Content-Encoding: brand WOFF2 fonts curlwith--compressed, wherever a script or an application calls it- FreeType, which decodes compressed font tables, and therefore anything that renders text
- Language extensions in PHP, Ruby and Perl that wrap the C library
- Proxies and edge software, some of which decode Brotli during the TLS handshake for certificate compression
- The operating system's own
libbrotlidec, shared by everything that links it rather than vendoring
None of these is exotic. All of them are invisible to an inventory that stops at the product name.
Almost nobody has said they are affected
This is the part that should change how you read vendor silence.
Of the many projects that bundle this decoder, the number that publicly stated "we are affected" is very close to zero. One Python package named the CVE in its own changelog. Node.js published an advisory. Bun shipped the fix by bumping a dependency pin, silently, without mentioning it in the release notes.
Everyone else said nothing — including several who are affected and several who are not. Microsoft has published no advisory, and the .NET runtime vendors a vulnerable version. Debian lists Brotli as vulnerable and unfixed while marking its own Node.js package "unimportant" because it links the system library. Ubuntu has no notice at all. SUSE is tracking Node.js but not Brotli itself.
Silence here does not mean safety, and it does not mean exposure. It means nobody has looked on your behalf.
The automation will not catch this one
Three mechanisms that organisations rely on all fail on this CVE, and understanding why is more useful than the specific case.
The advisory has no package identifiers. The GitHub security advisory for this CVE is marked unreviewed with an empty affected-packages list. OSV carries only a Git commit range. So npm audit, Dependabot, pip-audit, cargo audit and govulncheck will not flag it against any dependency you declare. A clean dependency scan says nothing here.
Version strings are unreliable in both directions. The upstream fix landed in February 2026; the tagged releases carrying it came out in October. A project pinning a post-February commit is already fixed while reporting the old version number. A project pinning the released tag of the same number is vulnerable. Software composition analysis keyed on versions gets both cases wrong.
Vendored copies are invisible to the package manager. A library compiled into a binary does not appear in any manifest. The only ways to see it are a build-time SBOM, a binary composition scan, or reading the project's source.
What NIS 2 actually asks for here
Article 21 of NIS 2, transposed in Romania by OUG nr. 155/2024, requires policies on risk analysis and information system security, vulnerability handling and disclosure, and — explicitly — supply chain security, including the security of relationships with direct suppliers and service providers.
The directive does not mandate an SBOM. What it requires is that your measures be proportionate to the risk, and this episode is a clean demonstration that a product-level inventory cannot establish what the risk is.
Two consequences follow for an assessment:
- Vulnerability handling has to accept inputs that are not vendor advisories. If your process starts when a supplier sends you a bulletin, it never starts for a case like this, because most suppliers sent nothing.
- Supply chain security has to reach below the supplier. The question is not only whether your vendor has a security programme. It is what their product contains, and whether they will tell you when a component in it is vulnerable.
Four questions a component inventory has to answer
Not a tooling project. Four questions, answered for the systems that matter.
- What third-party components are compiled into each product we run? For software you build, this comes from the build system. For software you buy, it comes from asking the supplier for an SBOM — and the answer you get, or do not get, is itself a finding worth recording.
- Which of those components are shared across unrelated products? Compression, parsing, cryptography and image or font handling libraries are the ones that reappear everywhere, and they are the ones that turn a single upstream flaw into a dozen separate remediation tasks.
- For each component, do we take it from the operating system or does the product carry its own copy? This decides whether a distribution update fixes it or whether you are waiting on a vendor rebuild. It is also the difference between one patch and twenty.
- Who finds out when a component we do not directly install has a vulnerability? Name the person or the feed. For most organisations the honest answer today is "nobody", and that is the gap this CVE exposes.
What to do about this specific one
Update Node.js to 22.23.4, 24.22.1 or 26.12.1; Node 20 and earlier are end of life and receive no fix. Update the Brotli library itself to 1.0.10, 1.1.1 or 1.2.1 wherever you have it. Rebuild container images rather than assuming a base image rebuild reached you.
Then do the part that is worth more than the patch: take the list of products in your estate, pick the ten that process untrusted input from the internet, and find out what each one bundles. You will not finish it this week. You will find two or three things nobody knew were there, which is the point.
There is no evidence of exploitation of this flaw, it is not in CISA's Known Exploited Vulnerabilities catalogue, and the single public demonstration succeeded only intermittently on one architecture. The urgency is low. The lesson is not.
Where the inventory itself is the gap, an audit and compliance review under NIS 2 establishes what an assessor expects and what evidence satisfies it. Where the question is what an attacker reaches from one compromised component, an internal penetration test answers it. And where you are unsure what you publish to the internet in the first place, an external attack surface review builds that list from outside.
Sources: Node.js October 2026 security releases · Upstream Brotli fix commit, 27 February 2026 · Brotli 1.2.1 release · Imperva: Node2Shell · Debian security tracker
The downstream consumers named above were established by reading each project's pinned source revision, not by testing, and no exploitation of any of them has been demonstrated. Vendor and distribution status is moving daily. The CVE carries a 9.2 score from Google as CNA; Node.js rates it "high" without a number and NVD had not analysed it at the time of writing.
This article is general information, not legal or regulatory advice.

