In this article
PHP had a bad Wednesday. On 21 October 2026 the PHP project released fixes for every supported version and told users to update immediately, which is about as close to shouting as an open-source project gets. The two flaws behind it, CVE-2026-109618 and CVE-2026-109619, have been nicknamed PHP2Shell. PHP's security team rates each one 9.2 out of 10.
The bugs live in PHP itself, underneath whatever your site was built with, WordPress included. Clean application code doesn't help. The researchers who found them say a bare "Hello World" page on an affected version can be exposed.
What actually went wrong
Both flaws come down to memory that PHP thinks it has tidied away. It hasn't.
PHP serves websites from a pool of long-running worker processes. Each worker cleans up after one request before it takes the next. CVE-2026-109618 breaks the clean-up. When a request runs out of memory, PHP abandons it in a hurry, and in a few places it does so while a block of memory is only half set up. The shutdown code then reads that half-built memory as if it were real. If an attacker can trigger the out-of-memory error on purpose, they can steer what happens next. PHP's advisory shows how: a crafted file-upload request, for example one that piles an unlimited number of headers into a single part until PHP runs dry.
CVE-2026-109619 breaks the handover between visitors. Some of PHP's internal bookkeeping, such as error details and session state, points into the memory of the request being served. If that request dies badly, the pointer survives while the memory behind it is freed. The next request handled by the same worker can then trip over the stale pointer before PHP gets round to resetting it. Security people call this a use-after-free. It is one of the oldest routes to running code on a machine you don't own.
The confirmed result for both flaws is unauthenticated remote code execution. Someone with no account and no password runs their own commands on your server, with whatever access your website has.
Why this reaches servers everywhere
PHP is unglamorous and everywhere. W3Techs puts it behind roughly seven in ten websites whose server-side language is known. Wiz Research, the team that found PHP2Shell, had working attacks against WordPress and Drupal within two days of spotting the first bug, in their own test lab.
Age makes it worse. Wiz says every PHP version released in the last decade is affected by at least one of the bugs, going back as far as PHP 5.4. Anyone who has inherited a website knows how often those old versions turn up. Nobody is going to ship an official fix for them.
How a server runs PHP matters too. The worst case is Apache with mod_php, an older arrangement that never quite went away. PHP's advisory says the out-of-memory attack fires there during the upload itself, before a single line of your site's code has run. PHP-FPM, which sits behind most nginx sites and managed hosts, is harder to hit. Harder is not safe. The researchers validated an attack on FPM through PHP's session upload progress feature, which is switched on by default and works even if your site never starts a session, though that route needs the application to do something suitable first.
Is anyone exploiting it yet?
By most accounts, yes. Security firm watchTowr says its honeypot network recorded exploitation of both CVEs on disclosure day. Amazon's threat intelligence team has reported an attempt on 17 October, four days before the fixes were public, which suggests details were out before the patches were.
There are caveats. As of 22 October, the US Cybersecurity and Infrastructure Security Agency (CISA) had not added either flaw to its list of known exploited vulnerabilities, and the PHP Foundation said it knew of no working exploit at release. Code claiming to exploit PHP2Shell is circulating publicly anyway. Some of it will be junk.
Treat it as live.
The fixed versions
| PHP branch | First fixed release | Notes |
|---|---|---|
| 8.5 | 8.5.12 | Newest branch |
| 8.4 | 8.4.27 | Supported |
| 8.3 | 8.3.36 | Security fixes only |
| 8.2 | 8.2.35 | End of life on 31 December 2026 |
| 7.4 to 8.1 | No official release | Minimal source patches from the PHP security team; some Linux vendors ship their own |
| 5.4 to 7.3 | None | No fix from the PHP project |
One catch with Linux distributions. PHP gave distributions and long-term support vendors the patches in advance, and they often backport a fix into their existing package without changing PHP's version number. So an older-looking number may already be patched, and the right number on a server that was never restarted may not be. Check your vendor's security notice for the package, then check the running process.
What to do this week
Updating PHP is the only complete fix. PHP's advisory and the researchers say so in nearly the same words. The work itself is rarely hard. Doing it properly is where people slip.
- Find every PHP runtime you have. The live site, the staging copy, the old campaign site nobody remembers and the internal tool on a box under someone's desk. Each container counts on its own.
- Check the version the web server is actually using.
php -von the command line can report a different build from the one serving pages. Your hosting control panel, or a temporaryphpinfo()page deleted straight afterwards, will tell you what visitors are really hitting. - Update, then restart every PHP worker. Apache, PHP-FPM, queue workers and any other long-running PHP process keep the old code in memory until they restart. Installing the package and walking away leaves you exactly where you were.
- Rebuild container images. Pull a patched base image and redeploy. An old image keeps shipping the old PHP however many times you run
composer update. - Ask your host, in writing. On shared or managed hosting you can't patch PHP yourself. Ask which version you are on and when the workers were restarted. A good host will already have the answer.
Updating WordPress or Laravel does nothing for PHP2Shell. The flaw is in the PHP runtime underneath, which is a separate piece of software with its own updates.
If you genuinely cannot patch today
Some settings cut down the known attack paths. None of them closes every route, and PHP says so plainly. Use them to buy a few days.
- Set
session.upload_progress.enabled = 0in php.ini or the FPM pool configuration, then restart the workers. Setting it from inside the application withini_set()or a.user.inifile doesn't count. If you never use the feature, PHP suggests leaving it off even after you patch. - On PHP 8.5, set
fatal_error_backtraces = 0and restart. - Keep
post_max_sizelow. PHP suggests 8M for sites that take no uploads and 32M for those that do, withupload_max_filesizebelow it. - If your site never uses multipart forms (file uploads are the usual reason for them), block multipart requests at the firewall or CDN before they reach PHP.
- Switch on your CDN or firewall provider's PHP2Shell rule if they have one. Cloudflare and several others have shipped protections, but coverage depends on the provider and the attack path.
PHP also lists memory_limit = -1, which removes the predictable memory cap the main exploit leans on. Think hard before using it. You swap a code execution problem for a server that one greedy request can push out of memory, so it needs a container or cgroup memory limit behind it. Never use RLIMIT_AS or RLIMIT_DATA for that job. They trigger the exact failure the attack needs.
Signs worth checking in your logs
A clean log proves less than you'd hope here, because the attack can finish before PHP writes anything down. Still, these patterns are worth a look:
- unusually large or malformed
PHPSESSIDcookies - multipart requests followed by memory-limit errors
- bursts of HTTP 500 responses with no obvious cause
- PHP workers crashing or restarting more often than usual
If you find these from before you patched, treat the server as possibly compromised. Patching closes the door. It doesn't evict anyone who already walked through it.
One thing to test after patching
The fix changes how PHP behaves when a script runs out of memory. Instead of bailing out mid-task, it now stops at the next safe point, and above that there is a new hard ceiling where PHP simply kills the process. Shutdown handlers don't run when that happens. If your application lives close to its memory limit during big imports or overnight reports, run those jobs after updating and watch them. Better to find out on a quiet afternoon than at month-end.
The servers that will cause trouble
PHP2Shell will be patched and forgotten within months, by the people who patch. The trouble will come from servers nobody owns: the brochure site still running PHP 7 on a machine built in 2019, or the customer portal from an agency that has since closed its doors.
Our view is that every business running a PHP application should have one named person responsible for its runtime, with a date in the diary for when its version stops getting fixes. For PHP 8.2 that date is 31 December 2026. Ten weeks.
If you're not sure what your site runs on, or who would patch it, our maintenance and support team can check your PHP versions and get them updated. Or just get in touch.
Sources: PHP security advisory, 21 October 2026; PHP's technical advisories for CVE-2026-109618 and CVE-2026-109619; Wiz Research; watchTowr; Tenable FAQ.