php2shell: Detecting and Investigating CVE-2026-109618 and CVE-2026-109619

php2shell: Detecting and Investigating CVE-2026-109618 and CVE-2026-109619

Ajmal Kohgadai
Ajmal Kohgadai
October 21, 2026

PHP shipped emergency fixes for php2shell, a pair of critical flaws tracked as CVE-2026-109618 and CVE-2026-109619, on October 21. Exploitation had already begun: Cloudflare reported early attacks against the flaws before the patches shipped, and watchTowr reported it in the wild from its honeypot network. A host stays exposed until it is updated and its PHP workers have restarted.

The question security leaders ask after a disclosure like this one is whether anyone got in before the patch, and how soon the team can answer that. Answering it takes an accurate list of where PHP runs and a way to check each of those hosts for signs that someone exploited either flaw. This post covers both, using the directed approach to proactive threat hunting that starts from a named threat and the assets it can reach.

What php2shell is and which PHP builds are affected

php2shell is the name researchers gave CVE-2026-109618 and CVE-2026-109619, two critical flaws in the PHP interpreter that can let an unauthenticated web request run code as the web worker account. The same flaws can also disclose live worker memory, which may hold passwords, tokens, and keys, without executing code. PHP fixed both on October 21, 2026, in versions 8.5.12, 8.4.27, 8.3.36, and 8.2.35.

Details leaked on October 20, and the PHP security team scheduled its release for 14:00 UTC on October 21, a day ahead of the original embargo. The team rated both flaws CVSS v4.0 9.2. Its security advisory says they affect all PHP installations serving web requests, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed. The team considers the risk highest for mod_php, where a demonstrated exploit triggers from an unauthenticated request before any application code runs. CISA published an alert the same day calling for immediate patching.

The two CVEs reach code execution through different memory-safety failures:

  • CVE-2026-109618, "RCE via OOM corruption." Out-of-memory handling can interrupt PHP while request data is only partly initialized, and request cleanup can then treat the invalid data as valid. The advisory lists multipart request parsing among the triggers, including requests without a usable Content-Length, parts with unbounded header counts, and deeply nested field names.
  • CVE-2026-109619, "RCE via stale global state." State owned by one request can survive after its memory is freed, and a later request handled by the same worker can use it. The confirmed paths run through session upload progress handling and, on PHP 8.5, fatal error backtraces. Session upload progress is enabled by default and is reachable even if the application never calls session_start().

Which application sits on top of PHP makes little difference. Wiz, one of the research teams credited with reporting the flaws, demonstrated unauthenticated code execution against current WordPress, Drupal, and Joomla container images. Wiz also reported that exploitation does not depend on a flaw in the application's code. By its count, every PHP version released in the last decade is affected by at least one of the two flaws. Pre-auth code execution on a web server commonly ends with a web shell for persistent access, the pattern our web shell detection guide covers in depth.

PHP 8.1 and older no longer get fixes from the PHP project. The PHP team published minimal source backports for 7.4, 8.0, and 8.1 for anyone building from source, and some Linux distributions and LTS vendors ship backported packages.

Which of your hosts are exposed to php2shell

Scoping starts with an inventory. PHP usually runs in more places than the application owners' list suggests, including CMS and e-commerce sites, internal admin consoles, container base images, and vendor appliances that bundle their own interpreter. Prophet AI's PHP runtime inventory hunt reports each install's version, whether its branch still receives security fixes, and whether the host is reachable from the internet. The same list shortens the response to the next PHP vulnerability, because the installs, versions, and exposure are already known.

Work the list in order of exposure. Internet-facing hosts come first, and mod_php hosts come ahead of PHP-FPM, given the PHP team's risk assessment. End-of-life branches go into an upgrade plan.

A version string can mislead in both directions. Distribution packages often carry the fix under the original upstream version number, so a host that reports an 8.2 build below 8.2.35 may already be patched. Check the vendor's package changelog before escalating it. An updated package on disk also leaves a long-running PHP-FPM or Apache process on the old code until that process restarts. Compare each worker's process start time with the package install time.

Two configuration details affect exposure to CVE-2026-109619 on specific SAPIs. On mod_php, the advisory identifies php_value and php_flag settings in .htaccess or directory configuration as one route to the stale state, because Apache applies them before request startup. On PHP-FPM, the advisory treats setups where the web server passes PHP_VALUE or PHP_ADMIN_VALUE to the pool as exposed. Both are quick searches across web server configuration.

If a host cannot be patched today, the PHP team lists interim settings that reduce exposure to specific attack paths, and it warns that none of them makes an installation safe:

  • session.upload_progress.enabled=0, set in php.ini or the pool configuration rather than through ini_set() or .user.ini, followed by a restart of every worker.
  • fatal_error_backtraces=0 on PHP 8.5, also followed by a restart of every worker.
  • memory_limit=-1, enforced through php_admin_value so applications cannot override it, with a container or cgroup memory limit as the availability boundary.
  • post_max_size = 8M for applications that take no uploads, or 32M where uploads are required, with web server or proxy limits on multipart part count, header count, and nesting depth.
  • pm.max_requests=1 on PHP-FPM, if performance allows, so each worker is recycled after one request and cannot carry stale state into the next.

For applications that never accept uploads, the CVE-2026-109618 advisory also recommends blocking multipart/form-data requests at the web server or proxy.

What php2shell exploitation looks like in logs and telemetry

No indicator list had been published at the time of writing, so the checks below look for exploitation behavior. Each one follows from how the flaws work and comes with what normal looks like, because PHP workers produce some of these events in ordinary operation. Search from October 20, when the details leaked, through the time each host was patched and restarted, and further back where log retention allows.

Multipart requests outside normal upload traffic. In web server, proxy, or WAF logs, look for multipart/form-data POSTs to endpoints that never take uploads, and for multipart requests sent with chunked transfer encoding instead of a declared length. Legitimate uploads usually go to a short, known set of endpoints and declare their size.

Memory-limit errors and HTTP 500s after those requests. Wiz recommends watching for unusual multipart requests followed by memory-limit errors or repeated 500 responses. PHP logs out-of-memory fatal errors, when error logging is on, with one of the strings below. The second appears when no memory limit is enforced, including under the memory_limit=-1 mitigation above. Occasional memory errors from known report or import jobs are normal, while a cluster that follows multipart requests from one external source is a lead.

  • Allowed memory size of
  • Out of memory (allocated

Worker crashes and churn. Wiz also lists unexplained PHP worker churn as a signal. The CVE-2026-109619 advisory says an attacker's requests have to reach the same worker, and that running several workers lowers the success rate per request. Expect repeated attempts from one source as a result. Search PHP-FPM and Apache error logs for these strings, then line up the crash times against the access log to find the requests that preceded them:

  • exited on signal 11
  • exit signal Segmentation fault

Execution timeouts. The stale-state flaw can also be triggered by forcing a request to time out, so watch PHP and PHP-FPM logs for Maximum execution time of entries that cluster with the multipart traffic above.

Oversized or malformed session cookies. Wiz also lists unexpectedly large or malformed PHPSESSID cookies in responses. Default web server and proxy logs do not record response headers, so this check works only where a WAF or load balancer captures Set-Cookie values.

PHP workers spawning shells. Code execution runs as the web worker account, so whatever an attacker runs next usually starts as a child of a PHP worker process. In EDR or process telemetry, review shells, interpreters, and download tools started by these parents:

  • php-fpm, php-cgi, lsphp, frankenphp, httpd, and apache2 on Linux
  • php-cgi.exe on Windows servers running PHP under IIS, with w3wp.exe (the IIS worker) as its parent

Children such as sh, bash, curl, wget, python, perl, cmd.exe, powershell.exe, and certutil.exe need review, though some are expected. PHP's mail() function calls sendmail through /bin/sh on Linux, and some applications call external image or PDF converters through a shell. Baseline the parent-child pairs each host produced before October 20 and investigate the new ones. Our post on the SharePoint zero-day applied the same process lineage check to w3wp.exe. Our EDR alert investigation guide covers tracing a suspicious process back through its process tree.

What the worker account changed. Three more checks cover the period after a possible compromise:

  • New or modified files in the web root and other writable, web-served paths, where a web shell would be written.
  • Outbound connections from PHP worker processes to destinations the host had not contacted before October 20. PHP applications routinely call payment, email, and update services, so compare against each host's own history.
  • New persistence owned by the web user, such as user cron jobs, SSH keys, and CMS administrator accounts.

If a check returns a hit. Treat the host as compromised until an investigation rules it out. Preserve the web server, PHP, and PHP-FPM logs before log rotation removes them. Then rotate every credential the worker account could read, including database passwords in application configuration files. Rebuild from a patched image instead of cleaning the host in place. Our guide to automated incident response covers the containment workflow that follows a confirmed compromise.

How Prophet AI Threat Hunter covers php2shell

Prophet AI Threat Hunter runs the php2shell hunt automatically across customer environments, against the telemetry each customer has connected, on the scope and schedule each team sets. Vulnerable and end-of-life PHP installs come back flagged for patching. Any suspicious finding goes to Prophet AI SOC Analyst for a full investigation, which returns a determination with the queries and evidence behind it.

When indicators are published, Prophet AI Threat Hunter adds them to its emerging-threat hunts. Validated findings become candidate detections that go through the peer review described in our post on detection engineering in an AI-driven SOC. Our overview of AI threat hunting explains how an investigation's findings turn into hunts across the rest of the environment.

To run the php2shell checks across your own environment without writing the queries by hand, see how Prophet AI Threat Hunter handles it.

Table of contents
Add as Google Preferred Sources

Insights

Ajmal Kohgadai

Ajmal Kohgadai

As the Director of Product Marketing at Prophet Security, Ajmal drives marketing and growth strategies and helps security professionals see how AI is transforming security operations.