PHP2Shell: What It Is and How to Protect Your Sites
On October 21, 2026 the PHP project released emergency updates for two critical vulnerabilities, nicknamed PHP2Shell: CVE-2026-109618 and CVE-2026-109619. Together they let an attacker run their own code on a web server using nothing more than crafted HTTP requests. No login and no special access to the site are needed.
PHP powers roughly 70% of websites, including WordPress, Drupal, Joomla, Magento and countless custom applications, so this one is worth checking even if you don't think of your site as "a PHP site." If you run anything built on PHP, update it now.
Background
The PHP team planned a coordinated disclosure for October 22, but details leaked online on October 20. PHP posted an advance notice that day and shipped fixed releases on October 21. Security firms, including watchTowr and Cloudflare, reported exploitation attempts in the wild almost immediately, and CISA added PHP2Shell to its Known Exploited Vulnerabilities catalog on October 26. The UK's NCSC went as far as advising organizations to consider taking unpatched systems offline.
PHP rates both issues Critical, CVSS v4.0 9.2.
What the vulnerabilities are
Both bugs live in PHP itself, not in WordPress or any particular application, which is why they affect so many sites at once.
- CVE-2026-109618, memory corruption on out-of-memory. When a request runs PHP out of memory, PHP aborts it in a way that can leave request data half set up. The cleanup code that runs afterward then treats that data as valid. An attacker who can push a request past the memory limit, for example with a large or unusual upload, can turn that into code execution. Apache with
mod_phpis the most exposed, because the attack can succeed before any application code runs. - CVE-2026-109619, stale internal state. Some internal state can outlive the request it belongs to. A later request handled by the same PHP worker can then act on that leftover data, a use-after-free. PHP confirms this can lead to memory disclosure and remote code execution. The demonstrated attack uses the session upload progress feature, which is on by default and works even if your application never calls
session_start().
PHP states that all PHP installations serving web requests are at risk, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed.
Which versions are vulnerable
| PHP branch | Vulnerable | Fixed in |
|---|---|---|
| 8.5 | before 8.5.12 | 8.5.12 |
| 8.4 | before 8.4.27 | 8.4.27 |
| 8.3 | before 8.3.36 | 8.3.36 |
| 8.2 | before 8.2.35 | 8.2.35 |
| 8.1, 8.0, 7.4 | all versions | No official release. Source-code patches only; check your OS vendor. |
| 7.3 and older | assume vulnerable | No fix. Upgrade to a supported branch. |
A note on the 8.2 branch: it reaches end of life on December 31, 2026, so if you're upgrading anyway, consider moving to 8.3 or newer.
Step 1: Find out what you're running
Check the PHP version that actually serves your website, not just the command-line version. They are often different binaries, and servers commonly have several PHP versions installed side by side.
- The most reliable check is a
phpinfo()page served through your site. Delete it as soon as you've looked. - On the server, check each service, e.g.
php-fpm8.3 -v, and list installed packages:
# Debian / Ubuntu
dpkg -l | grep -E '^ii +(php|libapache2-mod-php)'
# RHEL / Alma / Rocky / Fedora
rpm -qa | grep -i php
Distribution packages can be fixed without the version number changing. Ubuntu, Debian, Red Hat and others often backport security fixes into an older-looking version. If your package version is below the numbers in the table, check whether your vendor's changelog mentions the CVEs before assuming you're vulnerable:
# Debian / Ubuntu
apt changelog php8.3 | grep -m1 CVE-2026-109618
# RHEL family
rpm -q --changelog php | grep -m1 CVE-2026-109618
On shared hosting or a managed platform, ask your provider directly whether PHP2Shell has been patched on your server.
Step 2: Update, then restart PHP
Updating is the only complete fix. Install your distribution's or vendor's patched packages, or the upstream releases listed above, then restart every PHP process: PHP-FPM, Apache if you use mod_php, and any application servers. Until they restart, the old, vulnerable code keeps running in memory.
# Example: Ubuntu with PHP-FPM
sudo apt update && sudo apt install --only-upgrade 'php8.3*'
sudo systemctl restart php8.3-fpm
Sites on PHP 8.1 or older are no longer supported by the PHP project. Your options are a vendor that provides backported packages, or upgrading to a supported version, which may also mean updating the application itself.
If you can't update immediately
PHP is clear that no configuration change makes an installation safe. The settings below only block some of the known attack paths. Treat them as a stopgap for days, not a substitute for patching:
- Limit who can reach the site. Put unpatched systems behind a VPN or IP allowlist, or take them offline if they aren't essential.
- Turn off session upload progress with
session.upload_progress.enabled = 0inphp.ini, the FPM pool or the server configuration, then restart every worker. Don't rely onini_set()or.user.ini; they apply too late. PHP suggests keeping this off even after patching if you don't use the feature. - On PHP 8.5, set
fatal_error_backtraces = 0. - Cap request sizes:
post_max_size = 8Mif the site doesn't take uploads,32Mif it does, withupload_max_filesizebelow that. Enforce similar limits at your reverse proxy or load balancer. - On PHP-FPM, if performance allows,
pm.max_requests = 1gives each request a fresh worker, so no leftover state carries over.
A web application firewall rule from your CDN or host can help as an extra layer, but attackers have already been seen trying to get around them.
Step 3: Check for signs of compromise
Exploitation began within hours of the release, so a server that stayed unpatched for any length of time should be checked even after you update. Save copies of your logs and configuration first, then look for:
- New or recently modified
.phpfiles in web directories, especially in upload folders - Unexpected cron jobs, user accounts or SSH keys
- Unexplained outbound connections from PHP processes
- Unusually large or deeply nested multipart (upload) requests in access logs, and PHP workers crashing or hitting their memory limit around the same times
If you find anything suspicious, treat the server as compromised: don't just delete the file you found. Rebuild from a known-good state and rotate the passwords, database credentials and API keys the site used.
Need a hand?
If you're not sure which PHP version your site runs, whether your host has patched it, or whether anything got in, get in touch and we'll check it for you. You can also run our free security scan for a quick outside view of your server.