PHP2Shell: October's Emergency PHP Release Fixes Two Remote Code Execution Bugs
PHP put out an unscheduled security release yesterday, October 21. PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix two critical bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619, which the researchers who found them are calling PHP2Shell. From php.net:
PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix two critical vulnerabilities that can allow unauthenticated remote code execution. All PHP users are strongly encouraged to update immediately.
These aren't Magento, Laravel or WordPress bugs. They're reached while PHP is still setting up the request, before your application code runs, so it doesn't matter how carefully that code was written. If a server runs PHP for the web, it needs the update.
The two CVEs
| CVE-2026-109618 | CVE-2026-109619 | |
|---|---|---|
| PHP's title | RCE via OOM corruption | RCE via stale global state |
| Advisory | GHSA-w8hw-w9fx-j79w | GHSA-6wmf-4rv5-p3rp |
| CVSS v4.0 | 9.2, critical | 9.2, critical |
| Login needed | No | No |
| Fixed in | 8.5.12, 8.4.27, 8.3.36, 8.2.35 | 8.5.12, 8.4.27, 8.3.36, 8.2.35 |
Both carry the vector CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N. Over the network, no account, nobody has to click anything, full impact. The two qualifiers that keep it below 10 are high attack complexity and "attack requirements present": an attacker has to get the server into a particular state first, and how easily that happens depends on the setup.
CVE-2026-109618 is about running out of memory at the wrong moment. When PHP hits its memory limit it jumps straight out of the request. The advisory says that in some places request memory is already reachable before it's fully set up, so the cleanup that runs afterwards reads half-initialized data as if it were valid. An attacker can cause that deliberately with oversized or malformed multipart form uploads, the kind of request any PHP site accepts.
CVE-2026-109619 is about state left behind between requests. A PHP-FPM or Apache worker handles one request after another, and some internal state (errors, sessions, extensions) can outlive the memory it points at. A later request on the same worker reads that freed memory before PHP resets it. The advisory names two confirmed ways in: session upload progress, which is on by default and works even if the application never calls session_start(), and PHP settings that raise a warning while they're being applied, before the request starts. On PHP 8.5 the new fatal_error_backtraces setting is a confirmed source of the stale state. Sansec says this bug can also leak freed worker memory back to the attacker inside a PHPSESSID cookie, which could include passwords, session tokens or keys from somebody else's request.
The fix for the first one changes how PHP handles running out of memory: it now stops at the next safe point, or exits the process outright if usage keeps climbing. The fix for the second resets the leftover state properly.
Which servers are affected
PHP lists PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. The advisories are specific about how far each one was proven:
- Apache with mod_php is the worst case. PHP validated full remote code execution over HTTP with default memory and input limits and a normal prefork setup. The
.htaccessphp_valuelines are one of the early-warning paths for CVE-2026-109619. - PHP-FPM, which is what most Magento and Laravel servers run, is susceptible to CVE-2026-109618 according to PHP's source analysis, though no complete exploit was shown against it. For CVE-2026-109619, the session upload progress path was validated against FPM as well as mod_php. The early-settings path only applies to FPM if the web server passes
PHP_VALUEorPHP_ADMIN_VALUE; pool settings and.user.inidon't trigger it. - FrankenPHP and LiteSpeed are likely susceptible according to the advisories, and not validated.
None of that makes FPM safe to leave. The advisory's own wording is that updating "is the only complete mitigation".
What's known about exploitation
The timeline below comes from Sansec's write-up, which cites the researchers. Calif reported the first bug to PHP on August 11 and Wiz Research reported the vulnerabilities on August 24, so the PHP team had about two months. Then details leaked on October 20. PHP posted an advance notice the same day, scheduling the release for October 21 at 14:00 UTC and saying it would go earlier if exploitation appeared.
After that, the reports don't agree:
- Cloudflare says its WAF rules were on by default for free and paid plans from 03:02 UTC on October 21, and that it "observed attack traffic targeting our customers". It doesn't say whether any of it worked.
- Huntress said it had not seen in-the-wild exploitation across its customer base as of 4:30 p.m. ET on October 21.
- Sansec's October 22 update walks back its own expectation of mass exploitation. In their words, "The public exploits do not work against a default PHP installation", and most public proofs of concept need a separate local file inclusion bug in the application.
Sansec also reports that Calif demonstrated working attacks against current releases of Magento, WordPress, Drupal, Joomla, Nextcloud, phpMyAdmin, Laravel and Symfony. We haven't reproduced any of these, and we can't tell you how hard it is to attack a typical store today. Exploits for bugs like this usually improve once the details are public, though, and these details have been public for two days.
Updating
Updating PHP to a patch release is a package upgrade and a restart. Patch releases only carry bug and security fixes, so on most servers the restart is the only part that needs planning.
If PHP comes from Ubuntu or Debian
Ubuntu and Debian backport the fix into the PHP version they already ship, so php -v won't change. A patched Ubuntu 24.04 server still reports PHP 8.3.6. Check the package version:
dpkg -l | grep -E '^ii +php[0-9.]+-(fpm|cli|common)'
and compare it with the fixed versions from Ubuntu's CVE page and Debian's tracker:
| Distribution | Package | Fixed version |
|---|---|---|
| Ubuntu 26.04 LTS | php8.5 | 8.5.4-0ubuntu1.5 |
| Ubuntu 24.04 LTS | php8.3 | 8.3.6-0ubuntu0.24.04.13 |
| Ubuntu 22.04 LTS | php8.1 | 8.1.2-1ubuntu2.28 |
| Ubuntu 20.04 LTS | php7.4 | 7.4.3-4ubuntu2.29+esm5 (Ubuntu Pro) |
| Debian 13 (trixie) | php8.4 | 8.4.27-1~deb13u1 |
| Debian 12 (bookworm) | php8.2 | 8.2.35-1~deb12u1 |
On those, apt update && apt upgrade brings it in.
If PHP comes from somewhere else
Many Magento and Laravel servers run PHP from Ondřej Surý's repository (ppa:ondrej/php) or a hosting panel, and Docker images use upstream builds. Those follow PHP's own numbering, so php -v should show 8.5.12, 8.4.27, 8.3.36 or 8.2.35 or later. We haven't checked when each of those channels published the new builds, so look before assuming:
apt-cache policy php8.3-fpm
On Docker, pull the new base image and rebuild. A container built yesterday morning still has the old PHP.
If a managed host runs PHP for you, Adobe Commerce Cloud included, ask them when it was updated on your environment.
Restart everything that runs PHP
A new binary on disk does nothing until the processes running the old one are gone. After the upgrade:
- Restart PHP-FPM, every version installed, for example
systemctl restart php8.3-fpm. A reload is fine for picking up new code, but after a PHP upgrade a full restart is the safe choice. - Restart Apache if PHP runs inside it as mod_php.
- Restart long-running PHP processes: Magento queue consumers, Laravel Horizon or
queue:work, Octane, and anything under Supervisor. They're not the web entry point the advisories describe, but they're still running the old binary.
Then check the running service started after the upgrade:
systemctl status php8.3-fpm
The Active: active (running) since time should be after the upgrade. The same check works for apache2.
If you can't update today
PHP's advisory lists interim settings and is clear they reduce exposure without making a server safe. They have to go in php.ini, the FPM pool or the web server config, not ini_set() or .user.ini, and every worker needs a restart afterwards:
; php.ini or FPM pool
session.upload_progress.enabled = 0
fatal_error_backtraces = 0 ; PHP 8.5 only
post_max_size = 8M ; 32M if the site takes uploads
upload_max_filesize = 4M ; must stay below post_max_size
The advisory recommends leaving session.upload_progress.enabled off even after patching if nothing uses it. Most Magento and Laravel applications don't. If grep -r PHP_SESSION_UPLOAD_PROGRESS across your code finds nothing, you can probably turn it off for good.
Two more measures come with costs:
memory_limit = -1with a container or cgroup memory cap. PHP lists it, but notes it's incomplete, and Sansec points out that without a PHP memory limit one request can use up the whole server's memory. Don't do this on a shared box.- Blocking
multipart/form-dataat the web server. Sansec suggests it, and it removes the main way into CVE-2026-109618, but it breaks file uploads, Magento admin product images included, and possibly some cart and checkout forms.
Hiding errors doesn't help. The advisory says lowering error_reporting, using @ or turning off display_errors doesn't protect against the early-warning path.
A WAF is a reasonable extra layer. Cloudflare's rules are on by default, including on free plans, and Cloudflare itself says to patch anyway. Sansec says the bugs run "before your store code and before Sansec Shield" and tells its own customers not to wait for a Shield rule. We use Sansec on client stores and have written about why. We have no commercial relationship with Sansec or Cloudflare.
PHP 8.1 and older
PHP 8.1 and earlier get no new release. For this one incident, the PHP security team published minimal source patches for 7.4, 8.0 and 8.1, which helps only if you build PHP yourself. Ubuntu fixed its own packages back to 14.04, the older ones through Ubuntu Pro. Commercial long-term support vendors have their own builds. Sansec notes that the official Docker php images won't get a fix for 8.1 or older.
If you're on one of these with no vendor behind it, the only way to get the fix is to move to a supported PHP. That's a bigger job than a patch, because the application and its extensions have to support the new version. Our Laravel version support and Laravel server requirements posts cover the Laravel side, and for Magento the 2.4.6 end-of-support post does.
PHP 8.2 itself reaches end of life on December 31, 2026, ten weeks from now. Today's 8.2.35 fixes these two bugs, but there won't be many more. PHP 8.6 is due on November 19, and 8.6.0 RC4 already includes the fixes. Our PHP 8.6 post covers what changes when you move up.
If you'd like help checking or updating your servers, get in touch. We look after PHP servers for Magento, Laravel and WordPress sites.
Frequently asked questions
What is PHP2Shell?
The name researchers gave to CVE-2026-109618 and CVE-2026-109619, two critical vulnerabilities in the PHP engine fixed on October 21, 2026. Both can let an attacker with no account run code on a web server, with the privileges of the PHP worker. PHP rates both CVSS v4.0 9.2.
Which PHP versions fix CVE-2026-109618 and CVE-2026-109619?
PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, all released on October 21, 2026. PHP 8.6.0 RC4 includes the fixes too, but it's a test release and not for production. Every earlier release on those lines is affected.
Is PHP 8.1 or PHP 7.4 affected?
Yes, and there's no new upstream release for them. PHP published minimal source patches for 7.4, 8.0 and 8.1 for anyone building from source. Ubuntu has fixed its php8.1 package on 22.04 and its older PHP packages through Ubuntu Pro. If your PHP came from somewhere else, ask that vendor, or move to a supported version.
Does PHP-FPM need to be patched, or only mod_php?
Both. PHP validated full remote code execution against Apache with mod_php. For PHP-FPM, the advisory for CVE-2026-109618 says source analysis shows it's susceptible but no complete exploit was demonstrated, and the session upload progress path of CVE-2026-109619 was validated against both mod_php and FPM. PHP's own guidance is that updating is the only complete fix, whichever server API you use.
Does my Magento, Laravel or WordPress code need to change?
No. The bugs are in PHP, and they're reached while PHP is setting up the request, before any application code runs. The fix is updating PHP and restarting it. Sansec, citing the researchers at Calif, lists Magento 2.4.9, WordPress 7.1.2 and Laravel 13.11 among applications demonstrated vulnerable. We haven't reproduced that ourselves.
Is PHP2Shell being exploited?
Cloudflare says it has seen attack traffic against its customers. Huntress said it had not seen exploitation across its customer base as of 4:30 p.m. ET on October 21. Sansec's October 22 update says the public exploits don't work against a default PHP installation and that most need a separate file inclusion bug in the application. Details leaked a day before the fix, so we'd treat it as urgent either way.
How do I check whether my server is patched?
If PHP comes from Ubuntu or Debian, check the package version: the distributions patch without changing the PHP version number, so php -v still shows the old one. On Ubuntu 24.04, php8.3 needs to be at least 8.3.6-0ubuntu0.24.04.13. If you build PHP yourself or use an upstream build, php -v should show 8.5.12, 8.4.27, 8.3.36 or 8.2.35. Then confirm the running PHP-FPM or Apache process started after the update.
Is there a workaround if I can't update PHP today?
Only partial ones, and PHP says none make a server safe. Turning off session.upload_progress.enabled in php.ini or the FPM pool, setting fatal_error_backtraces to 0 on PHP 8.5, and lowering post_max_size remove some of the confirmed attack paths. Restart every worker after changing them. A Cloudflare WAF rule helps too, but Cloudflare itself says to patch.