Article

Oct 23, 2026

PHP2Shell explained: who is affected, how to patch, and why updating WordPress is not enough

PHP2Shell (CVE-2026-109618, CVE-2026-109619) lets attackers run code on PHP servers with no login. Update PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 and restart.

By AtasAI

PHP2Shell: CVE-2026-109618 and CVE-2026-109619, how to patch

PHP2Shell is the name for two critical bugs in PHP itself: CVE-2026-109618 and CVE-2026-109619. An attacker can run code on your server with one request and no login. Every PHP version before 21 October 2026 is affected. Update PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, then restart all PHP workers.

Updating WordPress, Laravel or Composer packages does not fix this. The bug is in the PHP runtime on the server.

Quick facts

Field

Detail

CVE

CVE-2026-109618 (GHSA-w8hw-w9fx-j79w), CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp)

Name

PHP2Shell

Type

Unauthenticated remote code execution (memory corruption)

Affected versions

All PHP versions before the fixed releases. Reports say this goes back to PHP 5.

Fixed versions

8.5.12, 8.4.27, 8.3.36, 8.2.35 (released 21 October 2026, 14:00 UTC). 8.6.0 RC4 also has the fixes.

No fix

PHP 8.1 and older (end of life)

CVSS

9.2 (CVSS v4.0), Critical, for each CVE

Exploitation status

Widespread scanning and exploit attempts. Sources disagree on real compromises. No confirmed compromise was publicly documented when we wrote this.

Highest-risk setup

Apache with mod_php

What is PHP2Shell?

PHP2Shell is two security bugs in the PHP interpreter. Details leaked on 20 October 2026 under the name “php2shell”. php.net announced an emergency release the same day and shipped the fixes on 21 October 2026.

php.net describes the two bugs like this:

  • CVE-2026-109618: remote code execution through out-of-memory corruption.

  • CVE-2026-109619: remote code execution through stale global state.

In plain English, both bugs sit in the code PHP runs while it sets up an incoming request. This happens before WordPress, Laravel, your middleware or your login check runs.

  • CVE-2026-109618. If PHP runs out of memory while setting up a request, some internal data is left half built. The cleanup code trusts it anyway.

  • CVE-2026-109619. Some internal state lives longer than the memory it points to, so the next request on the same worker can act on stale data. The “session upload progress” feature, on by default, is one confirmed way to reach this bug.

So a security plugin, a framework update or a login page cannot stop the attack. PHP handles the request before your code runs.

Where vendors disagree

The official description comes from php.net and the php-src security advisories. Other researchers give different detail. Sansec describes use-after-free paths in the upload-progress unserializer and in fatal-error backtraces. SOCRadar says four bugs sit behind the two CVEs. We treat these as unconfirmed. For full technical detail, read the php-src GitHub advisories.

Am I affected?

You are affected if any of these is true:

  • Your server runs PHP and the version is below 8.5.12, 8.4.27, 8.3.36 or 8.2.35 on its branch.

  • Your server runs PHP 8.1 or older (no fix exists).

  • Your server has more than one PHP version installed, and any one of them is unpatched.

  • Your Docker image was built before 21 October 2026.

  • You patched PHP but did not restart PHP-FPM, Apache or your long-running workers.

Check the PHP version on the command line

php -v
php -v
php -v

Then list every installed version:

ls -1 /usr/bin/ | grep
ls -1 /usr/bin/ | grep
ls -1 /usr/bin/ | grep

Each one needs the patch, even if your site does not use it.

Check the version your web server really uses

Command-line PHP and web PHP (PHP-FPM or mod_php) can differ. Check the web version too:

  • Run the FPM binary directly, for example php-fpm8.4 -v.

  • Or create a temporary file with <?php phpinfo();, open it in the browser, read the version at the top, and delete the file at once. A public phpinfo() page gives attackers useful information.

Docker

Check the PHP version inside the running container, not on the host:

docker exec <container> php -v
docker exec <container> php -v
docker exec <container> php -v

An image built before 21 October 2026 is almost certainly unpatched.

Shared hosting and managed hosts

Check the PHP version in your control panel (for example the PHP selector in cPanel), or use the temporary phpinfo() method above. If you cannot see the exact patch version, ask your host in writing.

How to patch

The fix is always the same: install a fixed PHP version, then restart every PHP process. Workers keep the old code in memory until they restart. This includes PHP-FPM, Apache, Laravel Octane, Swoole, RoadRunner and FrankenPHP. Then check the version again, on the command line and in the web context.

Ubuntu and Debian (apt)

sudo apt update
sudo apt install --only-upgrade 'php8.*'
sudo systemctl restart php8.4-fpm   # repeat for each installed version
sudo systemctl restart apache2      # if you use Apache / mod_php
sudo apt update
sudo apt install --only-upgrade 'php8.*'
sudo systemctl restart php8.4-fpm   # repeat for each installed version
sudo systemctl restart apache2      # if you use Apache / mod_php
sudo apt update
sudo apt install --only-upgrade 'php8.*'
sudo systemctl restart php8.4-fpm   # repeat for each installed version
sudo systemctl restart apache2      # if you use Apache / mod_php

Confirm each version shows the fixed release: 8.4.27, 8.3.36 or 8.2.35.

Old Ubuntu releases. Ubuntu 20.04 and older do not get a patched PHP 8.2 from the usual PPA. The lowest patched path is Ubuntu 22.04. Plan a rebuild, and use the temporary measures below until then.

Docker images

Change the image tag to a fixed version and rebuild with --pull, so Docker downloads the new base image:

docker compose build --pull
docker compose up -d
docker exec <container> php -v
docker compose build --pull
docker compose up -d
docker exec <container> php -v
docker compose build --pull
docker compose up -d
docker exec <container> php -v
  • Official image: use a tag that names the fixed version, for example php:8.4.27-fpm.

  • serversideup images shipped fixed tags on 21 October 2026, for example 8.4.27-fpm-nginx.

  • Do not trust a floating tag such as 8.4-fpm until you check the version inside the container. Lando’s PHP images had not shipped a fix as of 22 October 2026.

Laravel Forge and Ploi

  • Laravel Forge: Forge does not patch PHP for you. Update PHP on each server from the Forge dashboard, for every installed PHP version. Removing an unused version also works.

  • Ploi: we found no Ploi notice for this release. Use Ploi’s PHP management, or SSH and the apt steps above.

  • Laravel Cloud: patched automatically by the platform.

  • Bref and DigitalOcean: both shipped updates. Redeploy to pick them up.

cPanel and shared hosting

Your host controls the PHP binary, so you cannot patch it yourself.

  1. Check the PHP version (control panel or temporary phpinfo()).

  2. If it is below the fixed version, open a support ticket and ask for the exact version installed.

  3. If your account offers several PHP versions, choose 8.4 or 8.5.

  4. If your site is on PHP 8.1 or older, plan an upgrade now.

Managed WordPress hosts

Managed WordPress hosts usually patch PHP for you. Do not assume it. Ask the host to confirm in writing that your site runs a fixed version, and check it yourself if the host allows phpinfo().

Why updating WordPress, Laravel or Composer is not enough

Your application runs on top of PHP. WordPress updates, plugin updates and composer update laravel/framework do not change the PHP binary on the server.

composer audit and GitHub Dependabot will not flag PHP2Shell. They check the packages in composer.lock, not the interpreter. A clean composer audit report does not mean you are safe. Check the PHP version on the server.

If you cannot patch yet

PHP 8.1 and older have no fix

PHP 8.1 and older are end of life, and no fix will come. Upgrade to 8.4 or 8.5. Skip 8.2: it reaches end of life on 31 December 2026. Until you upgrade, isolate the system: limit who can reach it, or take it offline.

Temporary measures

php.net says these measures only reduce exposure. They are not a fix.

  • Turn off session upload progress. Set session.upload_progress.enabled=0 in php.ini or the FPM pool config (not ini_set() or .user.ini), then restart PHP. This blocks one known path to CVE-2026-109619 only, not CVE-2026-109618. PHP recommends keeping it off after patching if you do not use it.

  • On PHP 8.5: also set fatal_error_backtraces=0.

  • Limit request size. Set a low post_max_size (8M without uploads, 32M with uploads), and limit size at the proxy too.

  • Memory limit. Some vendors suggest memory_limit=-1 through php_admin_value, with a container memory limit as the safety net. Test it first.

A WAF helps only if attackers cannot go around it

Cloudflare shipped emergency WAF rules on 21 October 2026, on all plans including Free. Turn on the Managed Ruleset in Block mode.

But a WAF only checks traffic that passes through it. If your origin server also answers requests sent directly to its IP address, an attacker can skip the WAF. Lock the origin firewall so it accepts web traffic only from the WAF’s IP ranges. We found this gap on more than one server during our own PHP2Shell response. It is easy to miss, because the site looks protected when you test it through its domain name.

Cloudflare calls its rules a stopgap: a new variant can pass until the next update. Also avoid community rules that block every PHPSESSID cookie. That is PHP’s default session cookie, so the rule breaks logged-in users.

Was it exploited?

Reports differ. Here is what each source said:

  • watchTowr: its honeypots saw exploitation of both CVEs in the wild on 21 October 2026.

  • CISA: its alert on 21 October 2026 said no exploitation was observed at publication. The CVEs were not in the CISA Known Exploited Vulnerabilities catalogue as of 22 October 2026.

  • Huntress: no exploitation seen on partner systems (21 October 2026, 20:30 UTC).

  • Wordfence: blocked more than 74,000 exploit or probing attempts, with no confirmed compromises.

Reports say most public proof-of-concept code crashes PHP workers rather than running code. Sansec later said mass exploitation is “less likely than we expected.”

Our summary: scanning and attempts are widespread, but confirmed compromises were not publicly documented when we wrote this. Patch now anyway. A crashing exploit can still take your site down.

Other PHP ecosystem vulnerabilities this week

Laravel token guard authentication bypass (GHSA-f9x3-7vq9-cph6)

  • Affected: laravel/framework below 12.68.0 and below 13.29.0. No fix is listed for 11.x or older.

  • Fixed: 12.68.0 and 13.29.0. The fix shipped in August 2026. The advisory was published on 19 October 2026.

  • Severity: Critical, CVSS v4.0 9.2.

  • What it is: the built-in token guard accepted a token that is not a string. On MySQL or MariaDB, a crafted value can match the wrong user, so an attacker can log in as that user on API routes that use this guard. The advisory does not name Sanctum or Passport.

  • What to do: run composer update laravel/framework. Search config/auth.php for 'driver' => 'token'. Unlike PHP2Shell, composer audit does flag this one.

Duplicator (WordPress) object injection: CVE-2026-82814

Reported by Wordfence, as covered by SecurityOnline. We found one source only.

  • Affected: Duplicator 1.5.17 and earlier, and Duplicator Pro 4.6.10 and earlier. The plugin has more than 1 million active installs.

  • Fixed: 5.0.0 (both editions).

  • Severity: High, CVSS v3.1 8.8. No known exploitation as of 22 October 2026.

  • What it is: an attacker posts a comment with a crafted PHP object. If an admin later backs up and restores the site, the installer can run commands (free) or delete files such as wp-config.php (Pro).

  • What to do: update to 5.0.0, then build new backup packages. Old archives still contain the vulnerable installer.

Bricksforge (WordPress) file upload: CVE-2026-85097

  • Affected: Bricksforge 3.1.8.9 and earlier, about 6,000 sites.

  • Fixed: 3.1.8.10.

  • Severity: Critical. SecurityWeek lists CVSS 9.8; Cybersecurity News lists 10.0.

  • Status: exploited in the wild. Patchstack saw automated attacks from 7 October 2026.

  • What to do: update, look for unexpected .php files in upload folders, and block PHP execution in wp-content/uploads.

Need help checking your servers?

AtasAI builds and secures PHP, Laravel and WordPress systems from Bali and New Zealand. We can check every server and container for PHP2Shell, confirm that your origins cannot bypass your WAF, and plan upgrades from end-of-life PHP. Book a PHP patch audit or penetration test.

Sources

FAQ

What is PHP2Shell?

PHP2Shell is the name for two critical bugs in the PHP interpreter: CVE-2026-109618 and CVE-2026-109619. They let an attacker run code on a server with one request and no login. PHP released fixes on 21 October 2026.

Which PHP versions fix PHP2Shell?

The fixed versions are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.6.0 RC4 also contains the fixes. PHP 8.1 and older will not get a fix.

Does updating WordPress or Laravel fix PHP2Shell?

No. The bug is in PHP itself, not in WordPress, Laravel or any plugin. You must update the PHP version on the server and restart PHP.

Will composer audit detect PHP2Shell?

No. composer audit and GitHub Dependabot check the packages in your project. They do not check the PHP interpreter on the server, so you must check the PHP version yourself.

Is a WAF enough to protect against PHP2Shell?

No. A WAF such as Cloudflare blocks known attack patterns, but Cloudflare calls its rules a stopgap. The WAF also helps only if your origin server accepts traffic only from the WAF’s IP ranges. You still need to patch PHP.

What should I do if I run PHP 8.1 or older?

No fix will come for PHP 8.1 or older. Upgrade to PHP 8.4 or 8.5. Until then, isolate the system or take it offline, and set session.upload_progress.enabled=0 to reduce exposure.

Atas Studio LLC © All rights reserved

Atas Studio LLC © All rights reserved