PHP2Shell series, 4 parts
Read in order, or jump to the part you need.
  1. What PHP2Shell is
  2. How the two bugs work
  3. How it was found, and the leak
  4. How to patch and protect your servers

Bonus: watch it in 3D

This is part 4 of the PHP2Shell series, and the one to read if you run or look after anything built on PHP. It covers how to find out whether you are exposed, how to patch, what to do if you cannot patch today, how to look for signs of attack, and what to do afterwards. Background is in part 1 and part 2.

The short version
Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or to your vendor's patched build. Do internet-facing servers first, and Apache with mod_php before anything else. Restart every PHP worker afterwards. Configuration changes are stopgaps: PHP's advisories say the update is the only reliable fix. Facts are as reported on 31 October 2026 and may change. Since 23 October, CISA has added both CVEs to its Known Exploited Vulnerabilities catalog, and PHP has flagged a related session upload-progress issue that the 21 October releases do not fix.

Step 1: find out whether you are exposed

CISA's alert recommends taking inventory of every system running any PHP version, including PHP embedded in other software, and patching internet-facing systems first. Qualys adds practical traps:

Your situationWhat to do
PHP 8.2 to 8.5, below the fixed versionUpdate to the fixed version, or your vendor's patched build.
PHP 7.4, 8.0 or 8.1No regular upstream fix. PHP provided limited source backports. Use a vendor or distribution build that carries the fix, apply the backport, or upgrade to a supported branch. CISA says systems on PHP 8.1 or earlier that cannot be updated should be taken offline.
PHP 7.3 or olderEnd of life with no fix from the PHP project. Plan an upgrade, and in the meantime isolate the system.
Managed hosting or SaaSAsk the provider. You cannot patch PHP from inside WordPress or a plugin.
ContainersRebuild from a patched base image and redeploy. Updating packages inside a running container is not the same thing.
Qualys: PHP installations with a known version, by support statusAbout 44 million supported (8.2 to 8.5)About 110 million on end-of-life branches (5.4 to 8.1)Bars drawn to scale. One vendor's customer data,not a census of the web.
Most installations Qualys can see are on branches that do not get a normal upstream fix.

Step 2: patch

BranchFixed version
PHP 8.58.5.12
PHP 8.48.4.27
PHP 8.38.3.36
PHP 8.28.2.35

After updating, restart every PHP worker (PHP-FPM, Apache, the lot). A patched binary on disk does nothing for workers still running the old one. On release dates, CISA and Qualys describe the releases as shipping on 21 October, while the php.net changelog lists 8.5.12 and 8.4.27 under 22 October, so match your records against the version number rather than the date.

Two later notes from php.net. On 26 October the project published updated Windows builds (8.5.12-1, 8.4.27-1, 8.3.36-1 and 8.2.35-1) that bundle a newer Brotli library for an unrelated vulnerability; the PHP versions themselves are unchanged. And the 8.2 branch reaches end of life on 31 December 2026, so a move to 8.3 or later is worth planning now.

Step 3: if you truly cannot patch today

Here is where much of the early advice online went wrong. The two bugs need different stopgaps, and a setting that helps one does nothing for the other. PHP's own security team made the same correction about the most repeated tip (Alexandre Daubois, PHP security team). The advisories say what applies to which:

BugPartial measures from PHP's advisory
CVE-2026-109618 (out-of-memory)Set and enforce memory_limit=-1 administratively, restart all workers, and confirm no pool, directory or app setting restores a finite limit. Keep post_max_size conservative and enforce decoded request size at the frontend. Lower max_input_nesting_level, and bound input variables, multipart parts, headers per part and uploads. If you do not use multipart form data, block it at the frontend.
CVE-2026-109619 (stale state)Set session.upload_progress.enabled=0 and restart workers. On PHP 8.5, also set fatal_error_backtraces=0. Where performance allows, pm.max_requests=1. Remove startup diagnostics and obsolete settings, and prefer startup configuration to per-request overrides.

Warnings that matter:

What about a firewall?

Cloudflare deployed firewall rules on 21 October at 03:02 UTC, before the public release. They are available on all plans including Free (on paid plans, confirm the PHP2Shell rules are in block mode), and Cloudflare adds a response rule that can block matching responses from your origin. Cloudflare itself calls this a stopgap that only covers traffic routed through it, and says attackers were already modifying payloads. Sansec notes that its own application firewall does not cover this, because the exploit runs inside PHP before application code. Keep any firewall protection on during and after patching, and still patch. If you cannot patch at all, CERT-EU recommends isolating internet-facing applications until a fix is applied and verified.

Step 4: look for signs of attack

Datadog recommends correlating these, because none is conclusive alone:

A related issue the 21 October releases do not fix

On 23 October the PHP project published an informational advisory about a separate session upload-progress issue, CVE-2026-115560. It describes an unlikely remote code execution route that needs an unusual setup: the session serialize handler set to php_binary or php_serialize in configuration, switched to php at runtime with ini_set() before session_start(), with upload progress still enabled. PHP says it will fix it in the regular release cycle and publish a full advisory with the next release. Until then it suggests setting session.upload_progress.enabled=0, the same setting already listed above for CVE-2026-109619. Set it in the server configuration, because the main advisory says it does not work if applied with ini_set() or .user.ini.

Step 5: after patching

  1. Restart workers and redeploy containers so nothing keeps running the old runtime.
  2. Keep session.upload_progress.enabled=0 if you do not need the feature. The advisory recommends this even after patching, and PHP's 23 October note suggests it until the next regular release.
  3. Treat secrets on exposed servers as possibly read. Researchers showed worker memory can leak passwords, tokens, API keys and TLS private keys. That is our recommendation, not a step the sources prescribe: if an unpatched server was internet-facing, rotate database passwords, API keys (including model provider keys), session secrets and certificates, starting with the most privileged.
  4. Cap blast radius for next time. Scope AI provider keys to one purpose and set spend limits, so a leaked key has a ceiling.
  5. Plan the upgrade off end-of-life PHP. Datadog notes the fix does not remove the underlying pattern, so similar bugs may appear, and older branches will not get fixes.

Is it being exploited?

Sources differ, and the picture changed through 21 and 22 October. Here is who said what:

SourceWhat it reported
Amazon Threat IntelligenceA honeypot attempt on 17 October, and more on 21 October with payloads suggesting multiple actors. Unclear whether they would work on real systems.
CloudflareAttack traffic against its customers, with attackers modifying payloads to evade rules.
watchTowrActive exploitation attempts against both CVEs from 14:19 UTC on 21 October.
CISAHad not observed exploitation when it published on 21 October, and neither CVE was in its Known Exploited Vulnerabilities (KEV) catalog as of 22 October. On 26 October it added both CVEs to KEV (due date for US federal agencies: 29 October) and updated its alert to say so.
Wiz (27 October)Saw a limited number of exploitation attempts and none that succeeded end to end in its own data. It had found no public proof of concept that works in general against an arbitrary target, though it says some partners privately hold exploits that work on various targets. Wiz points to a public honeypot report of confirmed code execution on a single-worker Apache mod_php setup as the strongest public evidence, and says the scanning that followed was a likely factor in the KEV listing.
SansecSays mass exploitation looks less likely than first feared and that public proof-of-concept code it was told about did not work on a default install. It does not say it saw attacks itself.

No source we read confirmed a successful break-in of a specific server. Some organizations, including BambooHR and several Dutch government and education sites, went offline as a precaution (The Hacker News). Our advice: assume scanning is under way, and do not rely on "the public exploits are unreliable." Attackers only need reliability on the common setups.

If you are building or running an AI product

AI products sit on PHP more often than their diagrams admit: a WordPress marketing site with a chat widget, a Laravel back office that calls a model API, a legacy admin panel in front of a new retrieval service. The risk that matters most there is worker memory, because the model keys, vector database credentials and tokens those integrations use can sit in it. Patch first, then rotate and scope the keys. Our AI agent security checklist and security review guide cover the application side, and part 3 explains why the time you have to react keeps shrinking.

Need help with PHP2Shell?
This is the kind of fix we help with. GreyScript AI helps teams find where PHP runs behind their websites and AI products, patch it in the right order, and secure what sits around it: where model keys and other secrets live, how the AI integration is built, and which credentials to rotate. We start with an inventory, then give you a short, ordered patch-and-rotate plan, backed by our AI governance and security audit. Book a 30-minute scoping call and tell us what you run.

Sources: PHP advisory for CVE-2026-109618, PHP advisory for CVE-2026-109619, CISA alert, Qualys write-up, Alexandre Daubois, PHP security team, Datadog Security Labs, Sansec, Cloudflare, Tenable FAQ, The Hacker News, PHP 8 changelog. Read 23 October 2026