TL;DR
On October 21, 2026, the PHP project released emergency updates for two critical vulnerabilities known as PHP2Shell (8.5.12, 8.4.27, 8.3.36 and 8.2.35). Both are rated CVSS 9.2, and either can allow an attacker to perform unauthenticated remote code execution.
Dynatrace helps customers discover affected PHP workloads and prioritize updates using runtime and business context, so teams can focus first on the services that pose the greatest risk to their business. Customers must apply the PHP updates to remediate the vulnerabilities.
The vulnerabilities affect the PHP runtime itself, not in a plugin, framework, or library. Updating PHP is the only complete fix. Newer PHP versions have an official patched release you can upgrade to. PHP 8.1 and earlier do not: the PHP team has not issued a patched release for them, so there is no fixed version to download. However, for 7.4, 8.0, and 8.1, the team has instead published source patches, which you would have to apply and rebuild PHP yourself. If that’s not practical, many Linux vendors ship the fixes as backports in their own PHP packages, so updating through your OS package manager may be another route.
Updating is urgent: the technical details of the vulnerabilities leaked before the planned patch release, and Cloudflare is already seeing attacks. Many organizations did not wait for the patch. In the Netherlands, the House of Representatives (Tweede Kamer) and the National Cyber Security Centre (NCSC) of the UK took their websites offline as a precaution.
What’s at risk?
Any server that uses PHP to serve websites is at risk, including setups based on PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed. The PHP team has confirmed working exploits against default configurations (GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp).
Affected versions:
- PHP 8.2 before 8.2.35
- PHP 8.3 before 8.3.36
- PHP 8.4 before 8.4.27
- PHP 8.5 before 8.5.12
Unsupported older versions of PHP are also impacted. Researchers traced the flaws back to PHP 5.4, although PHP’s advisory does not specify how far they go. Linux distributions often backport fixes without changing the version number, so check your vendor’s advisory before marking a server as vulnerable; for example, USN-8948-1.
The flaws were leaked ahead of the coordinated disclosure. Cloudflare reports attacks against its customers, with attackers modifying their payloads to bypass its firewall rules. Researchers have demonstrated working exploits; detailed technical write-ups are public (for example, Calif), and unverified exploit Proof of Concepts (PoCs) are circulating.
The potential impact is severe. A successful attacker can execute arbitrary code with the privileges of the web server process. That typically exposes credentials, database connections, user sessions, and customer data. CVE-2026-109618 can also leak process memory, including passwords, tokens, and API keys, without any code execution.
Immediate steps
Updating PHP is the only complete fix. Update to 8.5.12, 8.4.27, 8.3.36, or 8.2.35, or install your Linux distribution’s updated package. Distributions got the fixes ahead of time, so packages should already be available. If you run containers, rebuild your images.
For PHP 8.1 or older: Check your vendors’ security advisories for a backported fix or upgrade. If you build PHP yourself, the PHP team has published minimal patches for 7.4, 8.0, and 8.1.
If you can’t update immediately: only an update is a complete solution; configurations reported by the PHP team to reduce exposure to specific attack paths are listed below in the How to fix PHP2Shell vulnerability section.
To identify affected applications or detect potential exploitation attempts, run the queries in the How to detect PHP2Shell vulnerability with Dynatrace section of this blog post.
What is the PHP2Shell vulnerability?
PHP2Shell is the name given to two newly disclosed critical vulnerabilities in PHP itself. Both vulnerabilities come down to the same problem: PHP doesn’t clean up properly when a request fails halfway through. An attacker can deliberately cause that failure and abuse the mess it leaves behind.
CVE-2026-109618 (RCE via OOM corruption). An unauthenticated attacker can send a crafted multipart POST request that exhausts PHP’s per-request memory while PHP is still parsing the request—before application code or authentication runs. The abrupt failure leaves partially initialized internal data behind; during cleanup, PHP can misinterpret attacker-influenced memory and execute an attacker-supplied command with the privileges of the web server process.
CVE-2026-109619 (RCE via stale global state). An attacker first sends a crafted request that triggers a fatal condition and leaves a PHP worker holding a reference to memory that has already been freed. A follow-up request handled by that same worker can reclaim and shape that memory; when PHP uses the stale reference, the attacker can redirect execution to an attacker-supplied command, again gaining an initial foothold as the web server account.
The bugs were found by Calif.io, Wiz, OpenAI, and Quarkslab. Once word got out, things moved fast:
| When (UTC) | What happened |
| October 20, 15:20 | A Hacker News post hints at critical PHP flaws |
| October 20 | PHP announces an emergency release. watchTowr confirms details had leaked ahead of the October 22 embargo |
| October 21, 03:02 | Cloudflare’s firewall protections go live |
| October 21 | Several government organizations take websites offline as a precaution |
| October 21, 13:34 | PHP Foundation publishes both security advisories on GitHub |
| October 21, 14:00 | Fixed versions are released |
How to fix PHP2Shell vulnerability (CVE-2026-109618, CVE-2026-109619)
Updating PHP is the only complete fix. The PHP team makes it plain that no setting fully mitigates the risk. If you can’t update immediately, the following configuration can help you reduce the risk. Make them in the main server configuration in a way that applications can’t override it (php.ini, the PHP-FPM pool, or Apache configuration), then restart every PHP process:
Against the OOM corruption:
- Configure limits to prevent controllable OOM
- Set
memory_limit=-1. - Set a low
post_max_size. Keepupload_max_filesizebelowpost_max_size. Enforce limits for the decoded request size, input field count, multipart part count, header count, and nesting depth in front of the PHP application. - Prefer container or cgroup limits over
RLIMIT_ASandRLIMIT_DATA.
- Set
- If not used, block
multipart/form-datarequests before they reach PHP.
Against the leftover-state bug:
- Set
session.upload_progress.enabled=0, which is active by default and allows exploitation even if no call tosession_start()is made. - For PHP 8.5 specifically, set
fatal_error_backtraces=0to block a confirmedmod_phpexploit. - If possible, limit the number of requests a worker may execute to 1 using
pm.max_requests=1. This ensures memory is cleaned because each worker process is respawned after every request. - Eliminate diagnostics from all INI configuration applied before request initialization.
- On application level: Eliminate fatal errors and timeouts on attacker-reachable paths.
For further details, refer to the GitHub security advisories (GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp) and the security advisory on php.net.
How to detect PHP2Shell vulnerability with Dynatrace
By having RVA and/or OneAgent running, Dynatrace customers can leverage data collection that is already in place. Dynatrace already knows which version of PHP monitored processes run. The following DQL query identifies monitored processes running potentially affected PHP versions.
smartscapeNodes "PROCESS"
| fieldsAdd technologies = arrayConcat(process.software_technologies.php, process.software_technologies.os)
| expand technologies
| filter technologies[type] == "PHP"
| fieldsAdd php_version = if(technologies[version] != "", technologies[version])
| summarize {
php_version = takeAny(php_version),
// Collect if the process has confirmed public internet traffic
process.has_public_traffic = if(takeAny(process.has_public_traffic), "CONFIRMED", else: "NOT_CONFIRMED")
}, by: {id}
| parse php_version, "INT:major '.' INT:minor '.' INT:patch"
// Filter out fixed PHP versions
| filterOut major == 8 AND (
(minor == 2 AND patch >= 35) OR
(minor == 3 AND patch >= 36) OR
(minor == 4 AND patch >= 27) OR
(minor == 5 AND patch >= 12)
)
| fieldsKeep id, php_version, process.has_public_traffic
Use the following log query to investigate memory errors, timeouts, and PHP worker crashes. These events can help identify suspicious activity, but do not by themselves confirm exploitation.
fetch logs
| filter matchesValue(content, {
"*Allowed memory size of*",
"*Maximum execution time*",
"*exit signal Segmentation fault*",
"*exited on signal 11*",
"*PHP Fatal error*"
})
Additionally, look for Problems detected by Dynatrace related to PHP processes, specifically out-of-memory errors and timeouts.
A common next step for an attacker is to run reconnaissance commands such as whoami, uname, or id, and, later on, spawn shells. When process execution logs are collected and available in Dynatrace, investigate unexpected commands or shell processes launched by PHP or web server processes as potential signs of compromise. Refer to the example in the React2Shell blog post, which shows how to set this up, and filter for apache2, nginx, php, php-fpm, and similar parent processes.
References and sources
- CVEs: CVE-2026-109618, CVE-2026-109619
- Vendor advisories: PHP security advisory, GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp, UK NCSC, CERT-EU 2026-018
- Research and coverage: Cloudflare, Sansec, SOCRadar, BleepingComputer
Patch first, then check what you’ve missed.
PHP2Shell is being actively exploited, and updating PHP is the only complete fix. Update to the patched versions 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or install your distribution’s patched package. Use the DQL query in this blog to identify monitored processes running potentially affected PHP versions, accounting for vendor backports. Then use Dynatrace logs and Problems to investigate memory errors, timeouts, and crashing PHP workers that exploitation attempts leave behind.
If you are a Dynatrace Managed customer, you will not have access to DQL. In this case, please contact your Dynatrace account team to learn how we can help.
Looking for answers?
Start a new discussion or ask for help in our Q&A forum.
Go to forum