Two flaws in PHP itself let attackers run code on your server without logging in. Here's what they are and how to fix them in about ten minutes.
On 21 October 2026, the PHP team shipped emergency security releases for two vulnerabilities, CVE-2026-109618 and CVE-2026-109619. Security researchers have nicknamed them PHP2Shell.
This isn't a bug in WordPress, Laravel or some plugin. It's in the PHP engine, so almost every site running PHP is affected, whatever framework it uses. Both issues are rated 9.2 out of 10 (CVSS v4), and both can let an attacker run code remotely with no account.
If you run PHP anywhere, on your own servers, a VPS, or a client's hosting, this is worth your attention today.
What the two bugs are
Both bugs are about memory that PHP handles wrongly between or during requests.
CVE-2026-109618: out-of-memory corruption. When PHP runs out of memory while it's still setting up a request, it can stop halfway. The cleanup that runs afterwards then treats half-built internal data as if it were valid. An attacker can trigger this with specially crafted multipart requests (the kind used for file uploads), even within your normal memory limits.
CVE-2026-109619: stale state between requests (use-after-free). PHP workers are reused for many requests. Some internal state from one request can keep pointing at memory that was already freed, and the next request on the same worker can use it. Researchers confirmed code execution through two features that are on by default: session upload progress, and fatal error backtraces in PHP 8.5. It can also leak memory contents.
The worst part is that on Apache mod_php setups, an attack can work before any of your application code even runs. Your own code being secure doesn't help.
Who is affected
Every way of serving PHP on the web is affected: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed. The PHP team considers mod_php the highest risk.
| PHP branch | Fixed in |
|---|---|
| 8.5 | 8.5.12 |
| 8.4 | 8.4.27 |
| 8.3 | 8.3.36 |
| 8.2 | 8.2.35 |
| 7.4 to 8.1 | No official release, only limited source backports |
| 5.4 to 7.3 | End of life, no fix from PHP |
One researcher traced the vulnerable code back as far as PHP 5.4. So if you still have an old client site on PHP 7.x, it's affected and won't get an official fix.
Is it being exploited?
Reports differ, so treat it as urgent either way. Amazon's threat team says it saw exploitation attempts starting 17 October, four days before the fixes came out, and Cloudflare and watchTowr also report attacks. Rapid7 has seen attempts but not confirmed successful attacks yet. Several proof-of-concept exploits are public, but each only works on a specific combination of OS, PHP version and server. Don't download and run them to "test" your server: some may contain malware.
How to check and fix it
1. Find every PHP installation. Start with anything facing the internet: production servers, staging, old client sites, and hosting panels like Plesk or cPanel that ship their own PHP. Don't skip servers just because they run a recent version.
2. Check the running version. On the command line:
php -v
The CLI version can differ from what your web server uses. To be sure, check what PHP-FPM or Apache is running (for example php-fpm8.3 -v), or look at phpinfo() on a page only you can reach, and delete that page afterwards.
3. Update. This is the only complete fix. Move to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 or later. If you install PHP from your Linux distribution's packages, the distro may ship the fix under its own version number, so check its security advisory rather than just the number. On Ubuntu or Debian:
sudo apt update && sudo apt upgrade
sudo systemctl restart php8.3-fpm # or apache2, depending on your setup
On shared or managed hosting, check your host's announcement or ask support whether they've patched.
4. Restart every PHP worker. Updating the files isn't enough while old workers are still running.
5. If you can't update today, reduce the risk. These settings lower your exposure but don't make the server safe. Set them in php.ini or the FPM pool config, not with ini_set() or .user.ini (that's too late), then restart all workers:
; CVE-2026-109619: session upload progress path
session.upload_progress.enabled = 0
; PHP 8.5 only: fatal error backtrace path
fatal_error_backtraces = 0
; CVE-2026-109618: avoid out-of-memory path (applications must not be able to override this)
memory_limit = -1
; Keep request sizes small
post_max_size = 8M
If your app doesn't accept file uploads, block multipart requests at your web server or load balancer. If you use Cloudflare, it has added firewall rules for known attack patterns, but only traffic through Cloudflare is covered. If none of this is possible quickly, consider taking the site offline until it's patched.
6. Old PHP 7.x sites. There's no official fix. This is the push you needed to upgrade them, or to ask your Linux distribution or an LTS vendor for a backported patch.
7. Check for signs of compromise. If a server was unpatched and exposed for days, look for unfamiliar PHP files, new admin users and unexpected outbound connections. Missing log entries don't prove nothing happened.
The takeaway
Most of us worry about bugs in our own code or in plugins, and forget that the language runtime can have them too. Keep a simple list of every server and site running PHP, and which version each uses. When the next emergency release comes out, that list turns hours of panic into a ten-minute job.
Sources
- Tenable: php2shell FAQ
- Rapid7: Critical unauthenticated RCE in PHP
- NCSC: Critical security issue affecting PHP
This article was written with help from AI and reviewed by the author. Originally published on Medium.
Top comments (0)