On October 21, 2026, at 14:00 UTC, the PHP project released emergency fixes for two critical vulnerabilities. On the same day, the Node.js project released fixes for ten vulnerabilities, the most severe of which was also critical.
Both the PHP vulnerabilities and the Node.js vulnerability carry a CVSS v4.0 score of 9.2, the threshold for critical. All three allow an unauthenticated remote attacker to execute code on a server. No login required. No credentials. No special access. Just a crafted HTTP request to an unpatched server.
The PHP vulnerabilities had already leaked before the official patch dropped, which means attackers knew what to target before defenders knew what to fix. WatchTowr confirmed exploitation in the wild within hours of the patch release.
The Node.js vulnerability had a fully working public proof-of-concept exploit by October 22, within 24 hours of the patch.
If your organisation runs PHP-based applications, including WordPress, Laravel, CodeIgniter, or any custom PHP backend, you need to patch immediately.
If your organisation runs Node.js applications, including Express, Next.js, Fastify, or any API built on Node.js 22.x, 24.x, or 26.x, you need to patch immediately.
This blog explains what each vulnerability is, exactly how to fix it, what to do if you cannot patch today, and why the broader lesson about patch management is the most important takeaway for every development team and IT manager in India.
PHP2Shell – CVE-2026-109618 and CVE-2026-109619
What It Is
The PHP development team and security community have named these two vulnerabilities “PHP2Shell.” Both are critical remote code execution flaws in the PHP core interpreter itself, not in any specific framework or CMS. If you run PHP, you are affected.
- CVE-2026-109618 – RCE via out-of-memory corruption. When PHP runs out of memory while handling a request, it starts an error cleanup process. CVE-2026-109618 is triggered when that cleanup happens while internal request data is only partially initialized. The result is memory corruption that a skilled attacker can exploit to execute arbitrary code on the server.
- CVE-2026-109619 – RCE via stale global state. Request-owned internal state in PHP can survive after its backing memory has been freed. This use-after-free condition creates a window where an attacker can influence what code gets executed.
Both vulnerabilities affect all PHP installations that serve web requests, including Apache with mod_php (which PHP rates as the highest-risk configuration), PHP-FPM, php-cgi, FrankenPHP, and LiteSpeed.
These findings rank among the most severe vulnerabilities discovered in PHP. The underlying flaws had been present for decades, but demonstrating their exploitability required an exceptionally complex chain of steps.
Which PHP Versions Are Affected and What to Update To
| Your current version | Vulnerable? | Update to |
|---|---|---|
| PHP 8.5.x (below 8.5.12) | Yes | 8.5.12 |
| PHP 8.4.x (below 8.4.27) | Yes | 8.4.27 |
| PHP 8.3.x (below 8.3.36) | Yes | 8.3.36 |
| PHP 8.2.x (below 8.2.35) | Yes | 8.2.35 |
| PHP 8.1.x, (8.0.x, 7.4.x) | Yes | Backported patch available (no new official release from php.net) |
| PHP 7.3.x and older, PHP 5.x | Yes | No upstream fix. You must upgrade. |
If you are running PHP 7.3 or older, there is no official patch. These branches are end-of-life. Migration to a supported PHP version is now a security emergency, not a deferred project.
Step-by-Step Fix for PHP2Shell
- Step 1: Check your PHP version immediately.
php --version
Note which version you are running and compare it against the table above.
- Step 2: Update via your package manager.
On Ubuntu or Debian:
sudo apt update
sudo apt upgrade php
On CentOS, RHEL, or AlmaLinux:
sudo dnf update php
On servers managed through a hosting control panel such as cPanel or Plesk, update PHP through the PHP version manager in the control panel.
- Step 3: If you manage PHP without a package manager, download the fixed release directly from php.net. PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35 are all available.
- Step 4: Restart the PHP service and web server after updating.
sudo systemctl restart php8.4-fpm
sudo systemctl restart apache2
# or nginx if applicable
sudo systemctl restart nginx
- Step 5: Verify the update was applied.
php --version
Confirm the version number matches the patched release.
- Step 6: Scan your servers with the php2shell-scanner released by Searchlight Cyber. This free open-source tool tests whether a host remains exposed to CVE-2026-109618 and CVE-2026-109619 after your update. Run it to confirm.
- Step 7: If you absolutely cannot patch today (legacy application dependency, change freeze, etc.), apply these temporary mitigations. These reduce attack surface but do NOT fully fix the vulnerabilities. Patch as soon as possible.
For CVE-2026-109619 only:
- In PHP 8.5, set
fatal_error_backtraces = Offin php.ini - In PHP-FPM, set
pm.max_requests = 1in the pool configuration
PHP itself states that no configuration change fully mitigates these vulnerabilities. These are delay tactics, not solutions.
Node2Shell – CVE-2026-111497
What It Is
Node2Shell, also called HTTP2Shell, is CVE-2026-111497. It is an out-of-bounds write in the Brotli decoder that is compiled directly into the Node.js runtime binary.
Brotli is a data compression format used extensively in HTTP to reduce transfer sizes. Node.js includes a built-in Brotli decoder in its core runtime. That decoder has a flaw: a crafted Brotli data stream can cause the decoder to write outside its allocated memory bounds. Node.js classifies the result as a remote code execution vulnerability.
The attack can arrive from two directions. Inbound: when your Node.js application accepts Brotli-compressed request bodies from users or clients. Outbound: when your application makes HTTP requests and receives a Brotli-compressed response from a server the attacker can influence or control.
Imperva demonstrated working code execution on the official Node.js 24.22.0 Linux arm64 image with no debugger and no custom build, simply by sending crafted Brotli data. They published this proof of concept on October 22, one day after the patch.
The vulnerability was discovered by Khai Tran and Sylvie Mayer of OpenAI Codex Security, reported privately, and fixed in the October 21 Node.js release.
An important clarification: the npm package named “brotli” is unrelated. Updating the npm brotli package does NOT fix this vulnerability. The vulnerable code is compiled into the Node.js runtime binary under deps/brotli. The runtime itself must be updated.
Which Node.js Versions Are Affected and What to Update To
| Your current version | Vulnerable? | Update to |
|---|---|---|
| Node.js 26.x (below 26.12.1) | Yes | 26.12.1 |
| Node.js 24.x (below 24.22.1) | Yes | 24.22.1 |
| Node.js 22.x (below 22.23.4) | Yes | 22.23.4 |
| Node.js 20.x and all older versions | Yes | No fix. Upgrade to a supported line. |
| Bun below 1.4.4 | Yes | 1.4.4 |
Node.js 20.x reached end-of-life on April 30, 2026, and receives no security fixes. If you are running Node.js 20.x or older, there is no patch available. You must upgrade your runtime to Node.js 22.x, 24.x, or 26.x to receive the fix.
Step-by-Step Fix for Node2Shell
- Step 1: Check your Node.js version.
node --version
- Step 2: Update using nvm (recommended for developer machines).
nvm install 22.23.4
nvm use 22.23.4
# or your preferred supported line
nvm install 24.22.1
nvm use 24.22.1
- Step 3: Update using the official installer if you installed Node.js directly. Download the patched version from nodejs.org.
- Step 4: Update using your package manager on Linux servers.
On Ubuntu via NodeSource:
sudo apt update
sudo apt upgrade nodejs
- Step 5: Verify the update.
node --version
Confirm it matches 26.12.1, 24.22.1, or 22.23.4.
- Step 6: Restart all Node.js application processes. The update only takes effect when running processes are restarted. A server running an old Node.js process against the new binary is still vulnerable until the process is restarted.
pm2 restart all
# or however you manage your Node.js processes
- Step 7: If you use Docker, update your base image.
FROM node:22.23.4-alpine
# or node:24.22.1-alpine or node:26.12.1-alpine
Rebuild and redeploy all containers. Containers running older base images remain vulnerable.
- Step 8: Check whether your application accepts Brotli request bodies. If your Express or Fastify application uses compression middleware that accepts Brotli from clients, ensure the runtime is updated. Also check if your application makes outbound HTTP requests to servers you do not control, as those responses could carry malicious Brotli data.
The Bigger Picture – Why Patch Management Is the Most Critical Security Practice Your Organisation Has
Two critical CVSS 9.2 RCEs on the same day, affecting two of the most widely used runtime environments in the world. Neither vulnerability is exotic. Neither required finding a new attack category. Both involved bugs that had existed for a long time, in code that runs on millions of servers, waiting for someone to find a way to exploit them.
The PHP flaws had existed for decades. The Brotli fix that would have prevented Node2Shell was committed to Google’s open-source Brotli repository on February 27, 2026. Eight months before Node.js bundled it. The fix was publicly available. It just was not in the runtime that companies were running in production.
This is the patch management problem in its most precise form. The fix exists before the attacker knows to look for the vulnerability. The deployment does not happen. The attacker finds the vulnerability. Now the race is between the attacker exploiting it and the defender deploying the fix that already existed.
For PHP2Shell, the details leaked before the official patch release. Attackers knew what to target before defenders received the official advisory. WatchTowr confirmed exploitation in the wild within hours. The race was measured in minutes.
For Node2Shell, a fully working public exploit appeared within 24 hours of the patch. Any organisation that takes longer than 24 hours to evaluate, test, and deploy a critical security patch is operating in a window where public exploit code exists and their systems remain vulnerable.
Most Indian organisations take much longer than 24 hours.
What a Real Patch Management Process Looks Like
This section is for CTOs, IT managers, and engineering leads who want to close the gap between “patch available” and “patch deployed.”
- Step 1: Maintain a current inventory of every runtime and framework version in production. You cannot patch what you do not know you are running. Every server, every container, every application should have a documented runtime: PHP version, Node.js version, Python version, Java version. This inventory should be updated automatically through your deployment process, not manually every quarter. If you do not know what PHP version your application is running today, that is the first problem to solve.
- Step 2: Subscribe to security advisories for every technology in your stack. PHP security advisories are published at php.net/security. Node.js security releases are announced at nodejs.org/en/blog/vulnerability. CISA publishes known exploited vulnerabilities at cisa.gov/known-exploited-vulnerabilities-catalog. GitHub Dependabot alerts cover your npm and Composer dependencies.
Subscribe to these. Don’t check them manually. Subscribe so that when PHP2Shell drops, you find out from an automated alert, not from a LinkedIn post.
- Step 3: Define a patching SLA based on severity. Critical CVSS 9.0+: patch within 24 hours. The PHP2Shell and Node2Shell timeline demonstrates that 24 hours is the window you have before working exploits are public.
High CVSS 7.0-8.9: patch within 7 days.
Medium CVSS 4.0-6.9: patch within 30 days.
Low: patch in the next scheduled maintenance window.
- Step 4: Separate patch testing from patch deployment. The reason most organisations take too long to patch is that they conflate testing a patch with deploying it. For a critical runtime update like PHP 8.4.27, testing means running your application’s test suite against the new runtime in a staging environment. If the tests pass, the patch is ready to deploy. This process should take hours, not days.
- Step 5: Automate the deployment path for runtime patches. Infrastructure as code and automated deployment pipelines make critical patching an executable decision rather than a manual process. When the PHP patch drops and your team confirms compatibility, the deploy command should take minutes, not days of coordination.
- Step 6: Track and report patch status to leadership. The SEBI CDSL adjudication order we covered earlier this year established that accumulated, unaddressed security gaps are foreseeable outcomes, not accidents. A board that can see that 70% of servers are running patched PHP and 30% are still pending is a board that can apply the right pressure. Patch status should be a visible metric, not a report buried in a quarterly review.
What to Check If You May Already Have Been Compromised
PHP2Shell was being actively exploited while most defenders were still reading the advisory. If your PHP server was public-facing and unpatched between October 20 and the moment you patched, assume you may have been targeted and investigate.
For PHP2Shell exposure:
Review your web server access logs for the period October 20 to your patch date. Look for unusual patterns: repeated requests with specific headers, requests that generated unexpected server errors, unusual response sizes, or traffic from IP addresses that do not match your normal user profile.
Look for any new files created in your web root or application directories during this window. A successful RCE exploit often writes a web shell to a writable directory to maintain access.
Check for any new scheduled tasks, cron jobs, or service configurations created during this window.
Review active outbound connections from your web server. A server that has been compromised may be beaconing to a C2 server. Unusual outbound connections to unfamiliar IPs are a signal.
For Node2Shell exposure:
Examine your application logs for unusual Brotli decompression errors, memory-related crashes, or unexpected process restarts.
If your application makes outbound HTTP requests, review the destinations and whether any of those responses could have carried malicious Brotli data.
Review the same indicators as above: new files, new scheduled tasks, unusual outbound connections.
If you find indicators of compromise: Isolate the affected server immediately. Preserve logs. Notify CERT-In within 6 hours if you confirm a breach. Engage a forensic investigation before any remediation to preserve evidence.
For Indian Development Teams Specifically
India’s technology sector runs a significant proportion of its web infrastructure on PHP. WordPress dominates corporate websites, NBFC customer portals, and banking product pages. Laravel is widely used for backend services across fintech, healthcare, and e-commerce. PHP is everywhere.
Node.js is the backbone of India’s fintech API layer. Payment gateways, UPI integrations, lending platforms, digital banking backends: the majority of modern Indian fintech infrastructure runs on Node.js. CVE-2026-111497 is a direct threat to this infrastructure.
A startup in Bengaluru running its payment API on Node.js 24.22.0 is vulnerable to an attacker sending a crafted Brotli-compressed request to its API endpoint. The RCE proof of concept is public. The window is open until the runtime is updated.
CERT-In’s 6-hour notification requirement applies to significant cybersecurity incidents. An RCE exploit that gives an attacker control of a production server running financial data qualifies. If your organisation is compromised through PHP2Shell or Node2Shell and you discover it, the notification clock starts immediately.
Under the DPDP Act, a breach that exposes personal data through a compromised web server is a personal data breach with notification obligations. The technical entry point, a memory corruption exploit in PHP or Node.js, does not change the regulatory consequence of the data exposure it enables.
Final Thought
The Brotli fix was committed on February 27, 2026. Eight months sat between the fix being available and the fix being deployed in Node.js.
During those eight months, every Node.js server in the world was running vulnerable code. The vulnerability was in Google’s public repository. Anyone who looked at the right commit could have found it.
The attacker who found CVE-2026-111497 did not discover a new vulnerability. They found a commit in a public repository and figured out how to exploit what it fixed.
This is the patch management reality that every development team and IT manager needs to absorb. The race is not between attackers and defenders finding the vulnerability. It is between attackers finding the fix and defenders deploying it.
In this case, the attacker won by eight months.
Next time, the gap should be measured in hours.
At Skeletos IT Services, we help Indian companies build patch management processes that close the gap between a critical advisory and a deployed fix, inventory runtime versions across environments, and implement monitoring that detects unusual server behaviour consistent with RCE exploitation. If you want to understand what your current patching posture looks like and where the gaps are, we can help you find out.
Note: This blog is based on verified security advisories from Morphisec, Snyk, CISA, WatchTowr, Qualys, Imperva, and the official PHP and Node.js project advisories, all published October 21-25, 2026. CVE details are from the official CVE records. Fixed version numbers are from php.net and nodejs.org official releases. Block indicators and patch versions should be validated against the original advisories before use in incident response.

