PHP2Shell and Node2Shell: Find, Fix, and Verify Across Your Web Apps and APIs

Key Takeaways

  • Neither flaw is in your application code. Every app and API on a vulnerable runtime inherits the risk. 
  • PHP2Shell (CVE-2026-109618, CVE-2026-109619) is fixed in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. 
  • Node2Shell (CVE-2026-111497) is fixed in Node.js 22.23.4, 24.22.1, and 26.12.1. 
  • Both are on the CISA KEV list. PHP2Shell was added October 26. Node2Shell followed on October 27. 
  • Qualys TotalAppSec tests the application and the APIs with four non-intrusive QIDs for detection of vulnerabilities and two intrusive QIDs for verification of fix.  
  • Patching fixes the runtime. A rescan confirms the fix worked and the application is no longer exposed. 

On October 21, fixes came out for PHP2Shell and Node2Shell, two critical flaws in the runtimes beneath your web apps and APIs. Five days later, PHP2Shell was on CISA’s Known Exploited Vulnerabilities list, and Node2Shell followed the next day. Attackers had been probing PHP2Shell four days before a patch even existed. 

With a timeline that short, the standard response of finding hosts, upgrading, and closing the ticket is not enough. Patched is a claim about a server. However, attackers really connect to the applications and APIs running on them. The question for application security teams is not whether PHP and Node.js were upgraded. It is whether an attacker can still reach the flaw through any application you run, and how you would know. 

This post covers how the two flaws impact your application estate, where most response plans break, and how Qualys TotalAppSec turns a runtime flaw into a finding you can fix and verify. 

A Runtime Flaw Is an Application Risk You Inherit 

Neither flaw is in your application code, which is why code scans, reviews and tests won’t flag them. Every application and API running on a vulnerable runtime inherits the exposure. 

PHP2Shell is a wide-scale problem. Qualys Threat Research Unit analyzed anonymized data from more than 10,000 customers and found 167 million PHP installations. Of the 156 million where the PHP version could be identified, 73% are on internet-facing assets. About 71% of the same 156 million run end-of-life or end-of-support versions that will likely never get a vendor patch, and only 199,000 were patched in the first 12 hours after disclosure.  

Node2Shell (CVE-2026-111497, a flaw in the Brotli decoder bundled with Node.js) hides in plain sight. Apps can be exposed even if they never call a Brotli API, because frameworks or dependencies may decompress attacker-controlled data. Node.js fetch() and Express 5 request-body parsing are examples of such attack vectors. As with PHP, end-of-life Node.js lines, including 25.x, 23.x and 20.x, get no fix and must move to a supported release. 

In practice, the exposed estate includes customer portals, CMS-powered sites, microservices and the APIs that connect them. It also includes anything that fetches or accepts compressed content. 

Attackers are not waiting for your patch cycle 

Details of PHP2Shell leaked before the coordinated release. Amazon Threat Intelligence spotted attackers targeting it four days before patches shipped, though early activity was mostly scanning, fingerprinting and non-working exploits. Then it escalated. CISA added PHP2Shell to its catalog on October 26 and Node2Shell on October 27. 

  • Confirmed code execution: a researcher’s honeypots recorded confirmed remote code execution with usable memory disclosure against Apache mod_php running PHP 8.4.26. 
  • Node2Shell: Public exploit code is available, and exploitation attempts have been observed in the wild. 
  • What’s at stake: Researchers have shown that PHP worker memory can be disclosed without authentication, exposing passwords, authentication tokens and API keys. 

To be precise: CISA hasn’t said which organizations were compromised, and the confirmed PHP exploit was on a deliberately favorable single-worker setup. The safe reading is that attackers have working exploits and are scanning widely, so treat any unpatched internet-facing app as a target. 

Find, fix and verify PHP2Shell and Node2Shell across your apps and APIs with TotalAppSec. 

Where Most Response Plans Break 

Most plans follow the same path: inventory hosts, upgrade, restart, close the ticket. That works until one of three gaps appears. In each case, the fix was applied in one place, but the attacker reaches the application through another. 

The application nobody owns 

You can’t test or patch what isn’t in your inventory. Forgotten microsites, acquired apps, and shadow APIs can run old runtimes, and they are the ones nobody is watching. 

A version string is a hint, not proof 

Proxies can strip the headers that reveal a PHP version, so a version-based check can miss a vulnerable app. Distribution builds can carry a backported fix under an older version number, so the same check can flag a fixed one. Neither a version banner nor a package list tells you how the application behaves when an attacker sends a request. 

Patched on disk is not patched in production 

Running processes keep the vulnerable code in memory until services such as PHP-FPM or long-running Node.js apps restart. Servers can also carry more than one PHP copy, so upgrading one leaves another. The fix only counts if the patched runtime is the one serving requests. 

A response built to end in proof 

An industry-neutral response has five steps, and the fourth is the one most teams skip. 

  1. Find every runtime and application. Inventory the web apps and APIs behind your internet-facing services and the runtimes under them. Include end-of-life versions, containers, vendor-bundled runtimes and apps nobody owns. 
  1. Scan, then rank by exposure. Start with internet-facing apps. Most teams can’t tell which apps use Apache mod_php or decompress untrusted Brotli data until they scan, so test first and rank the confirmed findings. 
  1. Fix, then restart. Upgrade to a fixed version or your distribution’s backported build, and restart every service that loads the runtime. If you can’t patch yet, apply the vendor’s interim mitigations and restrict access to the service. 
  1. Prove it from the outside. Retest the same applications and APIs, and treat any remaining finding as an incomplete fix. Also check for signs of compromise from before the patch, since exploitation began early. 
  1. Make it repeatable. The next trending CVE will start the same race. A standing process beats a scramble. 

How to detect PHP2Shell and Node2Shell in web apps and APIs with TotalAppSec 

Qualys TotalAppSec brings AI-powered, unified risk management to web apps and APIs. For PHP2Shell and Node2Shell, it tests the application itself over HTTP, the same path an attacker uses, not just the host. Six new QIDs cover both web applications and APIs. 

Two kinds of evidence: Potential findings (QIDs 520310 and 520404) read PHP version signals from response headers and application cookies. Confirmed findings (QIDs 533086 and 533203) observe behavior in the live application: how PHP handles a session ID with an invalid character, and how Node.js handles a crafted Brotli payload. Four of the six checks are non-intrusive and can be safely used in production. 

A safe way to verify: The two intrusive checks (QIDs 533068 and 533085) stress the application and can crash an unpatched one. Run them in a QA environment or on a patched production system, through the Trending Vulnerability Intrusive Options profile, so verification is a deliberate step with approvals and a maintenance window. 

A ready starting point for the next one: TotalAppSec includes two system-generated option profiles for scanning trending CVEs such as PHP2Shell and Node2Shell. To run a PHP2Shell and Node2Shell web application scan, choose a profile, select your apps by name or tag, and launch. The product tour below walks you through each step. Your scheduled scans may already include the four non-intrusive QIDs, because they are part of the Core, OWASP Top 10 and Everything option profiles and of AI-powered scans. 

Each finding attaches to a named application or API, so its owner can act on it. After the fix and restart, rescan the same applications. If a QID still reports, the patched runtime isn’t the one serving those requests. 

TotalAppSec shows what is exposed at the application and API layer. The runtime underneath lives on hosts, in images and in cloud workloads, where Qualys VMDR, TotalCloud and Container Security find vulnerable PHP and Node.js components. The Qualys Threat Research Unit covers that side in the PHP2Shell and Node.js blogs. 

See It in Action with This Interactive Product Tour 

The Next Runtime Flaw Is Already On Its Way 

PHP2Shell and Node2Shell showed how quickly a flaw in the layer under your applications can become an application risk. The pattern will repeat. The next critical runtime flaw may also sit outside your own code, and attackers will again move faster than most patch cycles. 

The teams that cope best aren’t the ones scrambling hardest in the first week. They already know which web apps and APIs they have, can see which are exposed, and can confirm a fix actually worked. Patched is a claim about a server. Proof is a finding about an application. Qualys TotalAppSec gives you that application-level view, with ready-made trending vulnerability profiles to start from. 

Know Your PHP2Shell Exposure and Mitigate It with Qualys 

Our free service finds PHP2Shell across your internet-facing assets, proves which servers attackers can exploit, and gives you a patch or mitigation path for each one, including versions PHP will never fix. 

Frequently Asked Questions (FAQs)

Which option profiles include the PHP2Shell and Node2Shell QIDs? 

The four non-intrusive QIDs (520310, 533086, 520404 and 533203) are in the Trending Vulnerability Options profile, and also in the Core, OWASP Top 10 and Everything option profiles. The two intrusive QIDs (533068 and 533085) are only in Trending Vulnerability Intrusive Options. 

Does an AI-powered scan test for the new QIDs? 

Yes, for the four non-intrusive QIDs. The two intrusive QIDs are not part of AI-powered scans, so run them separately with the Trending Vulnerability Intrusive Options profile. 

When can a scan miss PHP2Shell or Node2Shell? 

Version-based checks (QIDs 520310 and 520404) can miss an app when a web server or proxy strips response headers and hides the PHP version. The confirmed checks (QIDs 533086 and 533203) test how the application responds instead of reading version headers. 

How do I confirm a fix worked? 

Upgrade the runtime, restart the affected services, then rescan the same applications with Trending Vulnerability Intrusive Options on patched systems or outside production, with approvals and a maintenance window. If a QID is still reported, the fix is incomplete, so check that the patched runtime is serving requests. 

Source link

Leave a Reply

Your email address will not be published. Required fields are marked *