Zazmic Security Portal

PHP2Shell: Two Critical Unauthenticated RCE Flaws in PHP (CVE-2026-109618 & CVE-2026-109619)

8 min read

PHP2Shell: Two Critical Unauthenticated RCE Flaws in PHP (CVE-2026-109618 & CVE-2026-109619)

PHP has shipped emergency fixes for PHP2Shell, two critical flaws that let one unauthenticated request run code on almost every PHP web server. Patch to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 and restart every worker.

At a glance

On 21 October 2026 the PHP project released emergency patches for two critical flaws, together nicknamed PHP2Shell. Both allow an unauthenticated attacker to run code on a web server, and because the bugs live in the PHP runtime itself, applications are exposed even when their own code is secure. The weakness has been in PHP for more than a decade, so it reaches almost every PHP deployment in production today.

Patched releases are PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35, with source backports for the end-of-life 7.4, 8.0, and 8.1 branches. The single complete fix is to update PHP and restart all workers. Everything else buys time; it does not close the hole.

Disclosure was brought forward after exploit details leaked on 20 October. Cloudflare reported early exploit attempts before the patch shipped, and a working demonstration circulated publicly. Treat any internet-facing PHP server as exposed until it is patched.


What happened

The flaws were found by Wiz Research and the researcher known as Calif, working with OpenAI's Codex Security team, and were fixed together with the PHP security team and Google's Gemini team. Calif traced the vulnerable code lineage back to PHP research from 2004, which is why every supported branch and several unsupported ones are affected.

Coordinated disclosure was planned for later in the week. On 20 October a post on a public forum claimed the vulnerabilities were about to drop. The post was removed, but screenshots spread on social media, and watchTowr confirmed the leak. The PHP team responded by posting advance notice and moving the release forward to 21 October at 14:00 UTC.


The two vulnerabilities

CVE-2026-109618  memory corruption during request setup. When PHP hits an out-of-memory condition while a request is still being initialised, request data is left only partially set up. The cleanup routine then treats that invalid data as if it were valid, which opens a path to code execution. The same vulnerable path can be reached through the memory-limit handling, and an attacker can read live worker memory, exposing passwords, tokens, API keys, and certificates belonging to other requests handled by the same worker. PHP validated complete remote code execution over HTTP against Apache mod_php using default input and memory limits.

CVE-2026-109619  use-after-free from stale request state. PHP can keep request-specific internal state after the memory backing it has been freed. If the same worker then handles a later request, PHP may touch that stale state before it is reset, producing a heap use-after-free that can lead to memory disclosure and code execution. The trigger involves session.upload_progress, which is enabled by default and can reach session handling before PHP has finished setting up the request.

Both carry a CVSS v4.0 base score of 9.2. A score of 10.0 circulated during the leak; that figure was not the PHP project's rating.


Who is affected

The bugs are in the runtime, so every way of serving PHP over the web is in scope: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, and LiteSpeed. Exposure is highest on Apache mod_php, where a single unauthenticated request can trigger the first flaw before any application code runs. The second flaw reaches code execution on both mod_php and PHP-FPM, with the PHP-FPM path depending on an operation the running application performs.

Applications that bundle or sit on top of PHP do not shield you. Updating WordPress, Laravel, Drupal, or MediaWiki does not update the PHP runtime underneath them, so those sites remain vulnerable until the PHP packages themselves are patched.


Global organisations already responding

Within hours of disclosure, large organisations took services offline as a precaution rather than wait for confirmation of attacks:

  • BambooHR took its HR and payroll platform offline in the United States, Canada, and Ireland, warning customers that payroll processing could be interrupted.

  • In the Netherlands, MijnOverheid and DigiD (the national government and digital-identity portals), the website of the lower house of parliament, the national cyber-security centre (NCSC-NL), and several education systems were taken offline. NCSC-NL stated it had not seen the flaw abused at that point.

These responses are a useful signal for your own risk calls: organisations with mature security functions chose short, controlled downtime over the risk of an unpatched, internet-facing PHP server.


Exploitation status

Cloudflare reported early exploit attempts before the patch was available and deployed firewall rules as a stopgap. As of 11:26 UTC on 21 October, watchTowr reported no confirmed exploitation in the wild, and neither CVE was yet listed in CISA's Known Exploited Vulnerabilities catalogue. No successful breach had been publicly confirmed at the time of writing. Given that a working demonstration has circulated, the window between "no confirmed attacks" and "mass scanning" is expected to be short.

Immediate response: the first 24 hours

Work through these steps in order. The goal is to reach a patched, restarted runtime on every internet-facing host first, then widen to internal systems.

  1. Inventory every PHP installation, prioritising internet-facing systems. Do not limit the search to versions you think are outdated: every branch is affected. Include PHP bundled inside vendor appliances, control panels (cPanel, Plesk), and CMS stacks.

  2. Update PHP to a fixed release on each host. This is the only complete fix.

  3. Restart everything that runs PHP after updating: Apache, PHP-FPM pools, and any long-running PHP workers or queue consumers. An unrestarted worker keeps serving with the vulnerable code loaded.

  4. Chase third-party and vendor updates. Appliances and SaaS products that embed PHP need their vendor's patch; track and apply those as they land.

  5. Re-check after updating: review memory_limit and post_max_size. Reaching the hard memory limit now ends the process, which also stops shutdown handlers from running.

Patched versions

Patched versions

If you cannot patch immediately

These steps reduce exposure but do not fix the vulnerability. Use them only to hold the line until you can update, and restart workers after applying them.

  • For CVE-2026-109618: set memory_limit=-1 so individual applications cannot override it, keep post_max_size low, and enforce request-size limits at the web server or reverse proxy. Do not rely on RLIMIT_AS or RLIMIT_DATA, which can trigger the same vulnerable path.

  • For CVE-2026-109619: set session.upload_progress.enabled=0 and restart all workers. On PHP 8.5, also set fatal_error_backtraces=0. This reduces exposure but does not fully mitigate the flaw.

  • Edge controls: rate-limit and inspect multipart/form-data uploads at the CDN or WAF, and block unexpected upload endpoints. Cloudflare and other providers published managed rules for this issue.

  • Last resort: if you can neither patch nor apply mitigations in time, take the affected system offline until you can.

Detecting exploitation

No confirmed indicators of compromise were published at disclosure, so detection relies on behavioural signals rather than fixed signatures. Look for:

  • Unusual multipart/form-data requests followed by memory-limit errors or repeated HTTP 500 responses.

  • Unusually large PHPSESSID response cookies.

  • Unexplained PHP worker restarts.

  • PHP worker processes spawning child processes they never normally launch: shells (sh, bash, cmd.exe, powershell.exe), interpreters (python, perl), or download and network tools (curl, wget, nc, certutil.exe).

  • Command-line patterns associated with reverse shells: /dev/tcp/, fsockopen, mkfifo.

  • Reconnaissance commands run from the web server account: whoami, id, uname -a, ipconfig.

If you find signs of compromise

  1. Isolate the affected server from the network.

  2. Preserve web server and PHP logs before making changes, so the investigation has evidence to work from.

  3. Hunt for web shells, new or modified files in the web root, new cron jobs or scheduled tasks, and new user accounts.

  4. Rotate any credentials, tokens, API keys, or certificates that were resident on the host, since CVE-2026-109618 can disclose them from worker memory.

  5. Engage an incident-response provider if you cannot confirm the host is clean. Rebuild from a known-good image rather than cleaning in place where you can.

Zazmic Security recommendation

Treat this as a same-day patch for every internet-facing PHP host and a this-week patch for everything else. The combination of an unauthenticated runtime-level flaw, a decade of affected versions, a public demonstration, and early exploit attempts puts PHP2Shell in the same class as the PHP-CGI and Log4j events: the servers that were patched in the first day were the ones that stayed out of the incident reports.

If you run PHP at scale and want help inventorying affected hosts, validating patch coverage, or reviewing your edge and detection controls against this issue, the Zazmic security team can assist. Reach out and we will prioritise your internet-facing exposure first.


References

This advisory reflects information available as of 21 October 2026 and will change as the PHP team and researchers publish further detail. Verify version numbers and mitigations against the official PHP security announcement at php.net before acting.