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 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 |
|
No fix | PHP |
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 |
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.36or8.2.35on its branch.Your server runs PHP
8.1or 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
Then list every installed version:
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 publicphpinfo()page gives attackers useful information.
Docker
Check the PHP version inside the running container, not on the host:
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)
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:
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-fpmuntil 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.
Check the PHP version (control panel or temporary
phpinfo()).If it is below the fixed version, open a support ticket and ask for the exact version installed.
If your account offers several PHP versions, choose
8.4or8.5.If your site is on PHP
8.1or 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=0inphp.inior the FPM pool config (notini_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(8Mwithout uploads,32Mwith uploads), and limit size at the proxy too.Memory limit. Some vendors suggest
memory_limit=-1throughphp_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/frameworkbelow12.68.0and below13.29.0. No fix is listed for 11.x or older.Fixed:
12.68.0and13.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
tokenguard 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. Searchconfig/auth.phpfor'driver' => 'token'. Unlike PHP2Shell,composer auditdoes 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
.phpfiles in upload folders, and block PHP execution inwp-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.