PHP2Shell is not wp2shell, and this time there is no CMS patch

By Ricardo Ribeiro · · 4 min read · PHP, Security, DevOps

PHP2Shell is not wp2shell

In September the email in your inbox was about wp2shell, a bug in WordPress core. This week it is PHP2Shell, and the difference matters because almost everyone is reading the second one with the first one still in their head.

wp2shell was two WordPress bugs, fixed in 7.0.2, and the fix arrived as a CMS update. PHP2Shell is CVE-2026-109618 and CVE-2026-109619, both 9.2 under CVSS v4.0, both allowing unauthenticated remote code execution. They sit in the PHP engine, so no WordPress release and no plugin update fixes them. If you run PHP, you are in scope, and the only fix is the binary.

What shipped, and how fast it moved

On 21 October 2026 the PHP team released 8.5.12, 8.4.27, 8.3.36 and 8.2.35. The details leaked on 20 October, Cloudflare saw attack traffic at 07:43 UTC on the 21st, and the fixes appeared no earlier than 13:30 UTC. watchTowr reports exploitation in the wild. Governments took sites offline rather than run them unpatched: the Dutch House of Representatives, Tweakers, the Port of Rotterdam, Finland's Valtori, Denmark's Kombit and France's Interior Ministry.

Your host's email got the essentials right

DigitalOcean emailed its entire customer base, and if you got the same from your host, the useful parts held up: patch now, 8.1 and older have no official fix, and there is no complete mitigation. What it undersold was the urgency. The gap between patch available and mass scanning was hours, and the scanning started before the patch existed.

Two lines in that email are wrong

The email says that if you run WordPress or Laravel, you "may need software-specific patches directly from those providers." You do not. Neither bundles its own PHP, and there is no CMS patch to wait for. Sansec puts it in the first paragraph of their writeup: you cannot fix PHP2Shell from inside your store code. Follow that line literally and you spend a day waiting for a WordPress release that is not coming.

What does need vendor patches is a different thing: appliances and firmware that embed PHP, where you cannot update PHP yourself. The Dutch NCSC keeps a public list of exactly those. The email merged two situations into one sentence.

The same email says the flaws affect PHP from version 5 onward. The vulnerable code dates to 5.4.0, from 2012. Minor, except that knowing which branches are actually in scope is the whole job during a mass patch, and only 8.2 through 8.5 have an official fix.

What the bugs are, briefly

Both are use-after-free. In CVE-2026-109618, PHP aborts a request mid-parse when it hits memory_limit, and cleanup then trusts partially initialized request data. It also leaks worker memory back through the PHPSESSID cookie: passwords, session tokens and TLS keys from other requests, even if the app never calls session_start(). In CVE-2026-109619, request state survives a free and the next request on that worker uses it before initialization resets it. Calif, Wiz Research and OpenAI found them, and Sansec confirmed unauthenticated code execution against Magento 2.4.9 and ten other applications before the patch existed.

No mitigation, only a patch

php.net: "There are no complete mitigations, updating is the only safe choice." session.upload_progress=0 closes the confirmed session route and nothing else. memory_limit=-1 removes the controllable failure and lets one request eat the machine. PHP says to set those in the master php.ini or the FPM pool, not ini_set() or a .user.ini, which is awkward because that is what many shared hosts did.

I checked my own host

This site runs on HostGator shared hosting, so I do not control the PHP binary. Over SSH: ea-php83, version 8.3.36 built on 20 October 2026, the patched build, delivered before the public release. The master php.ini has session.upload_progress.enabled = 0 at line 1388, repeated in the account .user.ini under "added by webhost (mitigation)". php -v reports the CLI, not the web tier, but the session path points at ea-php83 too, so here they match.

What to do now

Get the version the web tier serves, from phpinfo(), your panel, or Site Health in WordPress. 8.5.12, 8.4.27, 8.3.36 and 8.2.35 are patched; anything below on the same branch is vulnerable. On a server you control, update the package and then confirm the version after the reload, because a failed upgrade looks like a successful one until you check. On RHEL, the Remi repo would not have updates on release day, so use the distribution packages. On 8.2, note the end of life on 31 December 2026.

Do not download that exploit

Code on GitHub claims to be a working PHP2Shell exploit, and some of it installs malware on the person running it. Do not download a PoC to test your own server. The test that matters is the version check above.

← All posts

Privacy · Cookies

Need a hand with a WordPress site that keeps breaking? See what I do and how I work.