Updated 23 October 2026: added PHP's follow-up advisory, CVE-2026-115560.
What happened on 21 October
On 21 October 2026, PHP and Node.js both released security fixes for flaws rated CVSS 9.2, critical, in their CVE records. Researchers and the press call them PHP2Shell and Node2Shell. Those names do not come from the projects: PHP2Shell is used by the security press and vendors, and Node2Shell was coined by Imperva's research team.
PHP2Shell covers two vulnerabilities, CVE-2026-109618 and CVE-2026-109619. Both are memory errors that can let an attacker run code on the server without logging in. PHP says every installation that serves web requests is affected, and the risk is highest on Apache with mod_php, where the demonstrated attack works before your site's own code runs. PHP 8.1 and older received no fix at all. On 23 October PHP added a smaller follow-up, CVE-2026-115560.
Node2Shell is CVE-2026-111497, a flaw in the Brotli decompression library that ships with Node.js. Node.js rates it high. It matters only when an application decompresses Brotli data an attacker controls. Node.js 20 and older get no fix.
Why care if your site is only a brochure? Remote code execution means someone else runs their code on your server: they can read form submissions and the database, change your pages, or use the server to attack others. A small site is a target because nobody is watching it. The official notices are on php.net and the Node.js blog.
Is anyone exploiting them? PHP and Node.js have not reported exploitation in the wild, and CISA's catalogue of known exploited vulnerabilities did not list any of the three on 23 October. Rapid7 reports it has not observed exploitation in the wild for PHP, but has seen reports of exploitation attempts. That is enough reason to patch this week.
How to find out if it concerns you
What to ask your agency or hosting provider
- Which PHP or Node.js version runs our site in production today, and was it updated after 21 October?
- If it is PHP 8.1 or older, what is the plan to move to a supported version, since no fix was released?
- If it is Node.js: does our app decompress Brotli data from outside, for example Express 5.0-5.3 or body-parser 2.0-2.3 accepting Brotli request bodies, fetch() reading Brotli from a server we do not control, or direct use of zlib? A bare HTTP server does not decode Brotli on its own.
- Who applies the update, and who confirms it to us in writing?
Signs that nobody is answering
If the question stays unanswered for 24 hours, treat the answer as "nobody". The same goes for replies that bounce between parties: the agency says the host updates PHP, the host says the version is the customer's choice. Other signs: nobody can tell you the version, the server access is in the name of a developer who left, or the last change to the site was the launch. If the site depends on one agency's accounts, read how to choose a CMS without agency lock-in.
What we did: there from the start, transparent with every client
Three things mattered more than the exact hours: we were there from the first day, we told every client plainly where they stood, and the problem got fixed. For every platform we had built or knew, with or without a contract, we followed the same order:
- Inventory. We listed which client platforms run PHP and which run Node.js, and the exact version in production. For the Node.js apps we checked whether the code decompresses Brotli data from outside.
- A message to every client, in business language: what happened, whether their site is exposed, what we propose and what we need from them.
- Where the exposure was real and the patch could not go in at once, we proposed a maintenance window until it could.
- We applied the patches, or asked the hosting provider to, and tested the key flows: forms, logins, payments.
- We confirmed in writing to each client: the version before, the version after, and what we checked.
The result: every exposed platform we look after was updated, and every client knew at each step what was happening, what it meant for their business and what came next. Nobody had to ask us whether they were affected.
Our own site runs on Next.js and Node.js. The day after the release we moved production to Node.js 22.23.4 and Next.js 16.4.2, and checked that our code does not decompress Brotli request bodies.
Here is a model message you can adapt and send to your own customers or ask your agency to send you:
On 21 October, PHP and Node.js released fixes for critical vulnerabilities that can let an attacker run code on the server. Your site runs on [PHP / Node.js, version]. It [is / is not] exposed. We propose to update it on [date], with [no downtime / a short maintenance window]. If the update cannot be done today, we recommend keeping the site in maintenance mode until then. We need your approval [and access to the hosting account]. We will confirm in writing when it is done, with the version before and after.
Why we did it for clients without a contract
Some of the sites we checked were delivered as projects, with no maintenance agreement after launch. We checked them anyway, because when it is about their site, we are their agency. The client does not know which version of PHP runs under their contact form, and should not have to.
The uncomfortable part: this works on goodwill. It depends on us having the time that week, on still having access, and on the client answering quickly. It is not a model anyone can rely on, which is exactly why maintenance exists: a written agreement that someone watches the stack, with a reaction time agreed in advance.
Putting the site into maintenance mode is a business decision
Taking a site offline until it is patched has a cost: hours without enquiries, orders or bookings. Leaving an exposed site online has a different cost: customer data, a defaced site, a server used to attack others, and the conversation with customers afterwards. A developer can tell you whether you are exposed. Whether to switch off is for whoever owns the business. Fifteen minutes and these questions are enough:
- Is the site exposed? For PHP, yes, until it runs a fixed version. For Node.js, only if it decompresses Brotli data from outside.
- Can the patch go in today? If it can, patch it and skip the maintenance window.
- What does the site hold: forms with personal data, customer accounts, payments?
- What does one day offline cost: enquiries, orders, bookings you can name?
- Can a static page with your phone number and email replace the site for a day?
- Who decides, and who tells customers?
If the site is exposed, holds customer data and cannot be patched today, a static page for a day usually costs less than the alternative.
What a maintenance contract should contain
So that next time you do not depend on goodwill, the contract should state:
- A reaction time for critical vulnerabilities, written down and agreed for your site.
- Who watches security advisories for your exact stack: language, framework, CMS and main dependencies.
- Planned major version updates, so you never sit on a version that no longer gets fixes, as PHP 8.1 and Node.js 20 did this week.
- A tested backup: how often it runs, where it is kept and when a restore was last tried.
- One named person you can call.
Some things are not worth paying for: a bundle of support hours that resets every month with no record of what was checked; round-the-clock on-call for every small issue on a presentation site; and automatic updates of everything, untested, which trade one risk for another. Our levels are on the maintenance page. Platforms we build under product development are handed over with documentation and accounts in your name, so whoever maintains them can work from that.
Ten questions for your website this week
- Which PHP or Node.js version runs our site in production today?
- Was it updated after 21 October 2026, and to which version?
- If it is PHP 8.1 or older, or Node.js 20 or older, when do we move to a supported version?
- If it is Node.js, does the app decompress Brotli data from outside?
- Who watches security advisories for our stack, by name?
- Who has the access to update the server, and is that account in our company's name?
- When did the last backup run, and when was a restore last tested?
- Is a reaction time for critical vulnerabilities written down anywhere?
- Who decides on maintenance mode, and who tells our customers?
- If our agency stopped answering tomorrow, could someone else take over from the documentation and accounts we hold?




