October has been a reminder that attackers don’t always need a flaw in your application. Sometimes the runtime is enough.
PHP and Node.js both shipped critical fixes on 21 October. The PHP flaws are known as PHP2Shell. Two days later, researchers demonstrated code execution on an unmodified Node.js build: Node2Shell. Different technologies. Different codebases. The same uncomfortable conclusion.
The application is not always the weakest link.
Both sets of vulnerabilities sit below the application layer, in the software that executes code and processes input. An organisation can follow secure development practices and keep its framework dependencies current. But an out-of-date runtime can still leave them exposed.
The pattern of response was familiar. Vulnerabilities were disclosed. Patches followed. Providers shipped protections. Researchers built proofs of concept. Organisations worked out their exposure. The industry has seen this many times; it’s why patch management remains a core security discipline.
What happened with PHP2Shell
PHP2Shell is a pair of critical vulnerabilities in PHP itself (CVE-2026-109618 and CVE-2026-109619), both rated 9.2 on CVSS v4.0. Details leaked on 20 October, ahead of a planned disclosure, and PHP brought its release forward to 21 October.
Both flaws involve how PHP handles memory when a request fails part-way through processing. Possible outcomes include denial of service, remote code execution and data exposure. Worker memory can hold passwords, authentication tokens, API keys and certificates from other requests.
Any PHP installation that serves web requests is in scope: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed, on versions back to PHP 5.4. Apache mod_php carries the highest risk, because a demonstrated exploit triggers before any application code runs.
A simple page with no custom code can be attacked, and updating an application such as WordPress or Laravel does not fix it. The risk sits in the platform running the application, not in application code.
For organisations with large PHP estates, the challenge was operational. Where is PHP deployed? Which versions are running? Which services face the internet? How quickly can updates be tested and rolled out?
Organisations that could answer those questions quickly were generally better positioned.
Then with Node2Shell
On 21 October, Node.js released security updates for CVE-2026-111497: a flaw in the Brotli decoder bundled with Node.js. Specially crafted compressed data can corrupt memory. The result can be a crash, disclosure of process memory or remote code execution.
Two days later, researchers at Imperva demonstrated a proof of concept, ‘Node2Shell’, on an unmodified official Node.js 24.22.0 build for Linux arm64. It took several attempts, and they did not test other builds. They reproduced it through Brotli-compressed request bodies and through responses an application fetches.
No exploitation of the Node.js flaw in the wild had been reported at the time of writing. PHP2Shell is different: watchTowr and Cloudflare have both reported exploitation attempts. Either way, once technical details are public, the time available to remediate shrinks quickly.
What can we learn
The Node.js advisory also highlights how interconnected modern software has become.
The vulnerability did not originate in Node.js itself. It originated in the underlying Brotli decoder, a component used by multiple products and ecosystems.
This is increasingly the reality of modern software development. Applications rely on frameworks, frameworks rely on libraries, and many of those libraries depend on shared open-source components.
As a result, a single vulnerability can have consequences far beyond the technology stack where it was first reported.
What we’re seeing
For many organisations, the hard part isn’t getting a patch. It’s understanding exposure.
Security teams have had to assess critical vulnerabilities across more than one runtime. In both PHP and Node.js estates, the first question is rarely how to apply the fix. It’s where the affected versions are running and whether they face untrusted traffic.
That’s harder in environments that have grown over time. Legacy applications, inherited infrastructure, containers and cloud-hosted services all blur the picture.
For customers concerned about exposure, we’re helping to:
- Identify affected PHP and Node.js deployments
- Validate runtime versions across servers, containers and cloud environments
- Prioritise internet-facing assets and critical business services
- Assess temporary risk-reduction measures where immediate patching isn’t possible
- Support testing and deployment of vendor fixes
- Verify that remediation is complete
The response varies by environment; the objective doesn’t: understand exposure, reduce risk and apply permanent fixes as soon as practical.
Security teams rarely get to patch everything immediately. Change approvals, testing and operational constraints leave a gap between disclosure and remediation.
WAF protections and temporary mitigations
For PHP2Shell, providers including Cloudflare, AWS, Microsoft Azure and Akamai quickly released WAF rules and mitigation guidance designed to identify or block known exploitation techniques. Despite the different solutions, the message was consistent: use WAF protections to reduce immediate risk, but prioritise deployment of the official PHP patches.
A similar approach emerged following disclosure of CVE-2026-111497. Vercel introduced protections for known attack patterns targeting vulnerable Node.js environments, while noting that these controls do not cover every possible attack path. Applications processing malicious Brotli-compressed responses still need runtime updates to eliminate the risk.
WAFs and platform protections can reduce exposure, but they don’t remove the vulnerability.
Mitigations are an important part of the response. Patching remains the long-term fix.
What to do now
- Update PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or to a vendor build that carries the fix. Linux distribution packages can carry the fix under an older-looking version number, so check the package changelog for the CVE rather than the version string
- Plan upgrades for end-of-life PHP. PHP 8.1 and older no longer receive updates from the PHP project, and PHP 8.2 reaches end of life on 31 December 2026. Until you upgrade, restrict public access
- Update Node.js to 22.23.4, 24.22.1 or 26.12.1. Node.js 20.x and older are end of life and receive no fixes
- Restart services and rebuild container images: a running process keeps the old code
- Review PHP memory settings after patching. The fix adds a hard memory limit; reaching it ends the process and stops shutdown handlers from running. Check memory_limit and post_max_size against what your application needs
- Keep WAF rules enabled as a temporary layer, and remove interim settings once patched
If you patched PHP late
Look for unusual multipart requests followed by memory-limit errors or repeated HTTP 500 responses, unusually large PHPSESSID response cookies, unexplained restarts of PHP workers, and PHP processes starting shells, interpreters or download tools.
If you find something, isolate the server and preserve the web server and PHP logs. Because the flaws allow memory to be read, rotate any credentials the affected application could access.
What we’re doing
We’re contacting affected clients directly. For most environments, patch the PHP or Node.js runtime. Each case calls for a different approach.
On some Azure Windows App Services, PHP 5.6 may be installed even when the application runs on .NET. If a PHP file is accessible, the PHP handler can execute it. PHP 5.6 is end-of-life and will not be patched. We rate the risk as low.
We’re proposing to set the PHP version to Off, which stops PHP files from being processed. Azure App Service doesn’t allow PHP to be removed, so it remains installed but inactive. The change recycles the app pool, so expect downtime for as long as the application takes to restart. The command is:
az webapp config set –name <name> –resource-group <resource-group> –php-version Off –subscription <subscription-id>
Before implementing, get approval from the application owner, make the change, then verify that PHP files can no longer be executed.
Patching is the answer
PHP2Shell and Node2Shell come from different technologies and different flaws. They point to the same reality: attackers target the platforms and components that applications depend on.
For defenders, the fundamentals haven’t changed:
- Understand your environment
- Keep visibility of the technologies you run
- Monitor advisories
- Test updates
- Deploy patches.
The organisations that coped best already knew where PHP and Node.js were deployed. They understood their exposure. And they had a process for new vulnerabilities.
When a critical vulnerability makes headlines, the hardest part is rarely finding the patch. It’s finding where it needs it.
Not sure which of your PHP and Node.js versions are patched? Ask us. We’ll tell you what we find.
