PHP RCE (CVE-2026-109618 & CVE-2026-109619): what broke, who is exposed, and how to fix it today

Two critical PHP flaws allow unauthenticated remote code execution. Patched in 8.5.12, 8.4.27, 8.3.36, 8.2.35. Check your servers in one command.

Dark banner reading: two PHP flaws let attackers run code before your app does. CVE-2026-109618 and CVE-2026-109619, patched versions 8.5.12, 8.4.27, 8.3.36 and 8.2.35.
Patched on 21 October 2026. Everything older than these four numbers is exposed.

On 21 October 2026 the PHP project shipped emergency releases for two remote code execution flaws in PHP core. If you run PHP anywhere — and you probably do — you need 8.5.12, 8.4.27, 8.3.36 or 8.2.35 today.

The 60-second version

  • Two CVEs: CVE-2026-109618 (RCE via out-of-memory corruption) and CVE-2026-109619 (RCE via stale global state). Both rated CVSS 9.8 Critical.
  • The bug is in PHP itself, not in a plugin, theme or extension you can switch off.
  • On the most common legacy setup — Apache with mod_php — the attack needs no login and runs before any of your application code does. Your WordPress password does not enter into it.
  • Working exploit code is public. Cloudflare says it saw real attacks before the patch shipped.
  • There is no complete mitigation. Updating is the fix.

Run one command to find out where you stand:

curl -fsSL https://blog.limewire.com/content/files/2026/10/php-exposure-check.txt -o php-exposure-check.sh
less php-exposure-check.sh      # read it first. always.
sh php-exposure-check.sh

That is our free self-check script. It makes no network calls, collects nothing, sends us nothing, and needs no root. More on it further down.

Prefer a browser? The same file is published from our verified LimeWire account @limewireofficial: download php-exposure-check.sh. No sign-up, no download cap, and the link does not expire.

What actually happened

A word on our credentials before the technical part: we are the company that spent the early 2000s giving a generation its first lesson in what an unexpected payload feels like. We have changed careers since. The instincts stayed.

PHP has a memory limit. When a script tries to exceed it, PHP does not simply stop — it performs a long jump out of whatever it was doing to unwind back to a safe point. That unwinding path, and the global state left behind by it, is where both vulnerabilities live.

An attacker who can make PHP run out of memory at a moment of their choosing can corrupt that state and steer execution. The second CVE is the sibling problem: state that should have been reset between requests survives into the next one. Both end at the same destination, which is arbitrary code running as your web server user.

The practical trigger is multipart request parsing — in other words, a file upload, or anything that looks like one. That is ordinary web traffic. It is not an exotic code path you can firewall away by blocking an endpoint.

Why this one is worse than the usual PHP advisory

Usual PHP CVEThis one
Needs an authenticated userUnauthenticated
Lives in an extension you can disableLives in core
Triggers inside your application logicTriggers before your code runs
Proof of concept appears weeks laterExploit code was public immediately

That third row is the one that matters most. Security plugins, login walls and application-level rate limits all sit inside PHP. If the request is weaponised during parsing, none of them have been reached yet. Researchers have been calling it "PHP2Shell", and for once the nickname is fair.

According to Wiz's analysis, the vulnerable code path has been present since PHP 5.4. This is not a regression introduced last month. It is something that has been sitting quietly under a very large portion of the web for over a decade.

The timeline, briefly

The coordinated release was scheduled for 22 October. Details leaked on the 20th — Chainguard broke the embargo — and the PHP project moved the release forward by a day. Cloudflare pushed a mitigating WAF rule to every plan including Free at 03:02 UTC on 21 October and reported observing exploitation attempts before the patch was publicly available. The SANS Internet Storm Center raised InfoCon to YELLOW.

If you are reading this and have not patched, assume the window has been open for days, not hours.

The only table that matters

BranchFirst patched releaseVulnerable range
8.58.5.128.5.0 – 8.5.11
8.48.4.278.4.0 – 8.4.26
8.38.3.368.3.0 – 8.3.35
8.28.2.358.2.0 – 8.2.34
8.1 and olderEnd of life — see below

Primary source: php.net release archive, 21 October 2026. Advisories: GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp.

Step 1: find every PHP you own

Almost nobody has an accurate list. PHP hides in places that are not "the web server": a webmail install, a monitoring dashboard, an invoicing tool a contractor set up in 2019, a staging copy nobody turned off, a Docker container three layers down in a compose file.

Finding files that people had forgotten they were sharing is, historically, the one thing we were extremely good at. We have redirected that talent somewhere more useful.

So we wrote a script that goes and looks. It is free, it is ours, and it is deliberately boring.

curl -fsSL https://blog.limewire.com/content/files/2026/10/php-exposure-check.txt -o php-exposure-check.sh
less php-exposure-check.sh
sh php-exposure-check.sh

Or grab it in a browser from our verified LimeWire account @limewireofficial: php-exposure-check.sh — published and checked by the LimeWire team, unlimited downloads, link never expires.

SHA-256, so you can confirm you got what we published:

c13cd5690c9d352c6a95e854602be2f330a0799435c05a8261037401fcf50255

Verify it with shasum -a 256 php-exposure-check.sh before you run it.

What it checks:

  1. Every PHP binary on disk, including the paths cPanel, Plesk, Remi and LiteSpeed like to use that a plain php -v will never show you.
  2. Running PHP-FPM worker processes — and whether a worker is still running an old binary you already replaced, which is the single most common reason people think they have patched and have not.
  3. Docker containers, checked from the outside.
  4. WordPress and Laravel installations on the host.

What it does not do: it makes no network connections, it writes nothing, it needs no root, and it has no telemetry of any kind. It is a shell script, served as plain text precisely so you can read it in your browser before you download it.

Exit codes, if you want to wire it into something: 0 everything found is patched, 1 something is vulnerable or end-of-life, 2 no PHP found at all.

We would rather you read it than trust us. Which brings us to an awkward family anecdote.

A brief word from the company that used to be a file-sharing app

Yes, we were that LimeWire. For a stretch of the early 2000s we were the single most efficient way to download a file that confidently claimed to be one thing and turned out to be something else entirely. An entire generation learned about executable payloads from us, by accident, usually around track four.

We have since gone legitimate — encrypted file sharing, AI tooling, a compliance department, the lot. But we do retain a certain institutional memory about what happens when untrusted bytes meet a trusting parser. Consider this article a long-overdue apology letter, written in the form of a patch advisory. We are not involved in this PHP bug in any way, and we would like that on the record.

Step 2: patch, by platform

Debian and Ubuntu

sudo apt update
sudo apt install --only-upgrade php8.3-cli php8.3-fpm   # match your branch
php -v
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2   # only if you use mod_php

Ubuntu users: this is covered by USN-8948-1.

RHEL, Rocky, AlmaLinux, CentOS Stream

sudo dnf update php php-fpm
php -v
sudo systemctl restart php-fpm

Remi repository users, read this: at the time of release Remi was behind the official patches, and php.net recommended temporarily switching to your distribution's own packages rather than waiting. Check what version dnf actually offers you before assuming an update fixed anything.

Docker and Docker Compose

This is where most people get it wrong, so it gets its own warning.

Pulling a new image does not patch a running container. The container keeps the binary it started with. You must recreate it:

docker compose pull
docker compose up -d        # recreates containers with the new image
docker compose exec web php -v    # verify, do not assume

The official images were rebuilt promptly. Measured on 22 October 2026:

ImagePHP
php:8.2-cli, php:8.2-apache8.2.35
php:8.3-fpm8.3.36
php:8.4-cli, php:8.4-fpm-alpine8.4.27
php:8.5-cli8.5.12
wordpress:latest8.3.36
wordpress:php8.28.2.35
drupal:latest8.5.12
nextcloud:latest8.5.12
joomla:latest8.4.27
matomo:latest8.4.27
phpmyadmin:latest8.3.36
mediawiki:latest8.3.36
roundcube/roundcubemail:latest8.4.27
bitnami/php-fpm:latest8.5.12

The Alpine trap: if you build your own image on Alpine, check your base tag. At the time of writing, alpine:3.21 — the current stable release — still offered php84-8.4.14, which is vulnerable. Only alpine:edge carried php83-8.3.36 and php84-8.4.27. A docker build --no-cache against stable Alpine will cheerfully produce a freshly built, still-vulnerable image.

cPanel, Plesk and shared hosting

You usually cannot run apt here, and you do not need to. Find the PHP version selector — MultiPHP Manager in cPanel, PHP Settings per domain in Plesk — and confirm the minor version your host offers, not just the branch. "PHP 8.2" in a dropdown tells you nothing; you need 8.2.35. If the panel only shows the branch, open a support ticket and ask the exact question: "which patch release of PHP 8.x is installed, and has it been restarted since the 21 October security update?"

If your host cannot answer that in plain terms, that is itself the answer.

WordPress specifically

PHP is the engine underneath WordPress. Updating WordPress core, your theme and every plugin does not fix this, because none of those are PHP itself. To see what you are running: Tools → Site Health → Info → Server. Then change it in your hosting control panel, not in WordPress.

Other common PHP software

SoftwareWhat to do
Laravel appsPatch the PHP runtime on the host or in the image. Composer packages are irrelevant here.
Nextcloudnextcloud:latest ships 8.5.12. Recreate the container.
Matomo, Joomla, MediaWiki, phpMyAdmin, RoundcubeOfficial images rebuilt — see the table above. Recreate, then verify with php -v.
Magento, PrestaShop, OpenCartPatch the underlying PHP-FPM or image. Test checkout on staging before production.
Keitaro and similar self-hosted trackersThese bundle their own PHP-FPM. Check inside the container or on the host and follow the vendor's own update channel — do not assume a host-level apt upgrade touched it.

If you are on PHP 8.1 or older

8.1 and everything before it is end of life. There is no release for you.

The PHP project did make a one-off exception and published source-only backports in php/php-src, on branches named like PHP-8.1-CVE-2026-109618-109619. Understand exactly what that is and is not:

  • It is source code. There is no tarball, no distribution package, no container image.
  • You compile it yourself, and you own the result.
  • You still receive no further security support. The next critical bug will not get this treatment.

Treat a backport as an emergency stopgap for a system you genuinely cannot move this week. The actual fix is getting to 8.2 or later. If you are on 8.1, you were already out of support before this happened; this is simply the bill arriving.

We are, admittedly, the wrong people to lecture anyone about end-of-life software. This company was declared dead in 2010 and came back in 2022. The difference is that a brand can do that. A PHP 7.4 install cannot.

If you truly cannot patch today

These reduce exposure. None of them make you safe. The PHP project's own position is that there is no complete mitigation.

  • Set memory_limit administratively so applications cannot raise it themselves.
  • Lower post_max_size to the smallest value your application tolerates.
  • Set session.upload_progress.enabled=0.
  • On PHP 8.5 only: fatal_error_backtraces=0.
  • Take anything off the public internet that has no business being there. A staging site or an admin panel reachable from everywhere is an unnecessary front door.
  • If you are behind Cloudflare, their managed rule went out to all plans including Free on 21 October. That is a speed bump, not a fix.

One mitigation that makes things worse

Do not use RLIMIT_AS or RLIMIT_DATA to cap PHP's memory. It sounds like exactly the right move and it is the opposite: those limits trigger the vulnerable code path themselves. If you have this in place as a hardening measure, it is now working against you.

Step 3: do not get scammed on the way

Every critical CVE is followed within hours by a second attack wave aimed at the people trying to fix the first one. It is already happening here.

We feel qualified to comment, if not proud of it. The second wave never needs a clever exploit; it only needs a frightened administrator in a hurry. Today the bait is called php-cve-scanner.exe. The file name is new. The trade is not.

Trust exactly four kinds of source:

  1. php.net — the project itself.
  2. Your distribution's security tracker (Ubuntu's USN, Debian's DSA, Red Hat's RHSA).
  3. The vendor's own release channel, for commercial software.
  4. github.com/php/php-src.

Release tarballs are signed. The signing keys live at php.net/gpg-keys.php. If you are downloading source, verify the signature — this is the one week of the year when it is unambiguously worth the two minutes.

Specific things to refuse right now:

  • Any "PHP vulnerability scanner" offered as a binary download from a site you had never heard of last week.
  • Urgent emails with attached "patches" or "assessment tools", however convincing the letterhead. Legitimate hosting providers link you to php.net; they do not attach executables.
  • Sites that materialised after 21 October offering a one-click fix. We read several while researching this piece; a recurring tell is a page that hands out a "checking tool" and then contradicts its own version numbers a few paragraphs further down. If a page cannot keep its own facts straight, do not run its binaries.
  • php2shell.com appears to be part of legitimate coordination around this issue, but it is not an official PHP project property and should not be treated as one.

And apply the same scepticism to us. Our script is served as readable plain text, with a published SHA-256, from our own domain, for exactly that reason. Read it, then run it.

Step 4: after you have patched

  1. Verify by reading, not by assuming. Run php -v in each place — host, container, and the FPM pool — not just one of them.
  2. Restart everything that embeds PHP. PHP-FPM, Apache with mod_php, and any long-running worker or queue process. An unrestarted worker is still vulnerable with a patched binary sitting on disk next to it.
  3. Re-run the self-check script. It explicitly looks for the "patched on disk, old version still running" state.
  4. Look backwards. Exploitation was observed before the patch existed. Check web server logs for unusual multipart POSTs around and before 21 October, look for new or modified files in web roots, and review scheduled tasks and PHP-FPM pool configs for anything you did not put there.

Frequently asked questions

Am I affected if I only run a WordPress blog?

Almost certainly yes. WordPress runs on PHP, so your site has a PHP version underneath it regardless of how simple the site is. Updating WordPress, plugins and themes does not change that PHP version — you change it in your hosting control panel.

Does a web application firewall protect me?

Partially at best. Cloudflare shipped a managed rule to all plans including Free on 21 October 2026, which helps. But the vulnerability triggers during request parsing, before your application runs, and exploit code is public. A WAF buys time; it does not replace the update.

I updated PHP but the scanner still says vulnerable. Why?

Almost always because the old process is still running. Replacing the binary on disk does not change the code already loaded in a running PHP-FPM worker or Apache process. Restart PHP-FPM and your web server, then check again.

Can I just disable file uploads instead of patching?

No. The trigger is multipart request parsing, which happens before your application decides whether it accepts uploads. Lowering post_max_size reduces exposure but does not close the hole.

What if I am stuck on PHP 8.1 or 7.4?

Those branches are end of life and receive no release. A one-off source-only backport exists in php-src for 7.4, 8.0 and 8.1, but you must compile it yourself and you get no further security support afterwards. Plan the move to 8.2 or later now.

Is this in CISA's Known Exploited Vulnerabilities catalogue?

Not at the time of writing — we checked and neither CVE was listed. That is a reflection of catalogue lag, not of risk. Exploitation has been observed in the wild.

Sources

Last verified 22 October 2026. Container versions in this article were measured directly with docker run on that date. If you spot something that has changed since, we would rather hear about it than not.