Read Time: 4 minutes

PHP2Shell: Critical Unauthenticated RCE Flaws in PHP Core (CVE-2026-109618 and CVE-2026-109619)

On 21 October 2026 the PHP project released emergency updates that fix two critical remote-code-execution vulnerabilities in the PHP runtime itself. Tracked as CVE-2026-109618 and CVE-2026-109619 (collectively dubbed PHP2Shell), both carry a CVSS v4.0 score of 9.2. They affect every PHP installation that serves web requests—PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, LiteSpeed and others—and can be triggered by an unauthenticated attacker before application code ever runs. Because PHP powers a large share of the public web, the flaws have been described as one of the more serious issues in years.

What the bugs actually do

CVE-2026-109618 is an out-of-memory (OOM) corruption issue. PHP uses longjmp() to abort a request when the memory limit is hit. In certain contexts the runtime can leave request-owned data only partially initialised. The subsequent request-cleanup code then treats that invalid memory as valid, producing a use-after-free or memory corruption that researchers demonstrated can be turned into full remote code execution. On Apache with mod_php a single unauthenticated request is enough under default settings; RCE has also been confirmed on PHP-FPM through application-level paths.

CVE-2026-109619 is a stale-global-state / use-after-free problem. Request-owned internal state (error handling, session data, extension state, etc.) can survive after its backing memory has been freed. A later request handled by the same worker process may then use that stale pointer before normal initialisation resets it. Confirmed entry points include the session upload-progress feature (enabled by default and reachable without calling session_start()) and, on PHP 8.5, fatal-error backtraces. Again, complete RCE was demonstrated against real applications on mod_php.

Both issues sit in fundamental parts of the interpreter—memory management and error handling—so they are independent of any particular CMS, framework or plugin. WordPress, Drupal, Laravel, Magento, Joomla and countless custom applications inherit the risk simply by running on an affected PHP binary. Estimates of exposed servers have exceeded 22 million.

Affected and fixed versions

Supported branches are fixed in:

  • PHP 8.5.12
  • PHP 8.4.27
  • PHP 8.3.36
  • PHP 8.2.35

PHP 8.1 and earlier are end-of-life and receive no official packaged releases, although the project published minimal source backports for 7.4, 8.0 and 8.1 for those who still build from source. PHP 8.2 itself reaches end-of-life on 31 December 2026, so sites still on that branch should treat 8.2.35 as a temporary step and plan a move to 8.3 or 8.4.

The vulnerabilities were discovered with the help of AI-assisted research (Calif, OpenAI and Wiz) and had existed in some form for more than a decade. An earlier audit had flagged related OOM handling problems, but concrete exploitability only became clear in 2026. A leak of CVE identifiers on 20 October forced the project to advance its planned release by a day; patches landed on 21 October. Early exploitation attempts were reported by multiple security firms even before the public fixes appeared.

Patching and interim mitigations

Updating to one of the fixed versions and restarting every PHP worker (PHP-FPM pools, Apache, etc.) is the only complete remediation. Old worker processes continue to run the vulnerable code until they are recycled.

If an immediate upgrade is impossible, the PHP security advisories list partial, temporary measures that block some confirmed attack paths but do not make an installation safe:

  • Administratively force memory_limit = -1 (and ensure no pool, .htaccess or application setting reintroduces a finite limit). Do not rely on RLIMIT_AS or RLIMIT_DATA; those still exercise the vulnerable path.
  • Set session.upload_progress.enabled = 0 and, on PHP 8.5, fatal_error_backtraces = 0. Restart every worker afterwards; ini_set() and .user.ini act too late.
  • In PHP-FPM, consider pm.max_requests = 1 to break the same-worker requirement for the use-after-free.
  • Keep post_max_size and request-size limits conservative at the web-server or reverse-proxy layer, and block multipart form data if the application does not need uploads.

These settings reduce exposure while you arrange the upgrade; they are not substitutes for the patched binaries.

Future precautions

Runtime vulnerabilities of this class underscore several longer-term practices:

  1. Inventory and rapid patching. Maintain an accurate inventory of every PHP binary—including those embedded in appliances, containers, vendor software and CI systems. Subscribe to the PHP security advisories and vendor channels so patches can be applied within hours, not days.
  2. Prefer supported branches and plan upgrades. Stay on actively supported PHP versions. Treat end-of-life branches as unacceptable for internet-facing workloads.
  3. Least-privilege worker isolation. Run PHP workers under dedicated, low-privilege users. Use containers or cgroup memory limits so a single compromised or crashed worker cannot exhaust the host. Prefer PHP-FPM over mod_php where operationally feasible; while both are affected, the attack surface and restart model differ.
  4. Harden default configurations. Disable features you do not use (session.upload_progress, unnecessary error backtraces, etc.). Enforce request-size and nesting limits at the edge. Avoid per-request INI overrides that can introduce early diagnostics.
  5. Monitoring and detection. Watch for anomalous multipart uploads, unexpected fatal errors, worker crashes, and spikes in memory usage. After any suspected exposure, hunt for webshells and unexpected processes before declaring the system clean.
  6. Support the ecosystem. The PHP Foundation has noted that sustained security work still depends on a small group of funded developers. Organisations that rely heavily on PHP can reduce future emergency cycles by sponsoring that work.

Conclusion

PHP2Shell is a rare, high-severity problem in the language runtime rather than in application code. Because exploitation can occur before any of your own logic executes, framework-level protections and input validation offer no defence. The fixes are already available; the practical work is to locate every affected deployment, upgrade it, restart the workers, and verify the new versions are running. Temporary configuration changes can buy a short window, but only the patched releases close the vulnerabilities completely. Treat this as an urgent operational priority and use the incident to tighten inventory, patching cadence and runtime hygiene going forward.

Leave a Reply

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