php2shell (CVE-2026-109618, CVE-2026-109619): What the October 2026 PHP Security Release Fixes and What to Do
The October 2026 PHP security update fixes php2shell, two critical bugs that can allow unauthenticated remote code execution. Here is what they are, who is at risk, how to update on common setups, and what to do on PHP 8.1 and older.
If you only read one line: update PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 today, restart every PHP worker, and check each PHP on the box with -v. Those releases fix php2shell (CVE-2026-109618 and CVE-2026-109619), the PHP security update of October 2026, which php.net says can allow unauthenticated remote code execution on PHP installs that serve web requests.
I am writing this on 21 October 2026, the day of the release, for store owners, developers and sysadmins running Magento, WordPress or plain PHP. Below is what the two bugs are in plain words, who is exposed, how to update on the setups I see most, and what to do if you are stuck on an old PHP.
Which PHP versions fix php2shell?
php.net published four releases on 21 October 2026. Both GitHub advisories list the same patched versions, and everything below them on each branch is affected.
| Branch | Fixed version | Status |
|---|---|---|
| PHP 8.5 | 8.5.12 | Supported, update now |
| PHP 8.4 | 8.4.27 | Supported, update now |
| PHP 8.3 | 8.3.36 | Security fixes only, update now |
| PHP 8.2 | 8.2.35 | Update now, end of life on 31 December 2026 |
| PHP 8.1 and older | No php.net release | Vendor backport, source backport (7.4, 8.0, 8.1) or upgrade |
Each release note carries the same line: there are no complete mitigations, updating is the only safe choice. I take that literally. If the people who wrote the fix say no workaround is complete, I stop looking for one and spend the time patching.
What are CVE-2026-109618 and CVE-2026-109619, in plain words?
Both bugs are about PHP cleaning up after a request that went wrong. Neither one needs a bug in your own code.
CVE-2026-109618, RCE via OOM corruption. When PHP runs out of memory it jumps straight out of the request. The advisory explains that this can happen while internal request data is only half set up, and the cleanup code then treats that half-built data as valid. An attacker can push PHP toward that out-of-memory point with crafted multipart requests, for example requests without a usable Content-Length, a part with a huge number of headers, or lots of empty file fields with nested names. The fix replaces that hard jump with a delayed soft stop at a safe point.
CVE-2026-109619, RCE via stale global state. A long-running PHP worker keeps some global state between requests. Some of it can point at memory owned by one request. If a fatal error, out-of-memory condition or warning leaves that pointer behind, the next request on the same worker can use memory that was already freed. The confirmed paths are INI warnings raised before the request starts, session upload progress handling, and fatal error backtraces on PHP 8.5.
The result in both cases, according to the advisories, is code running as your web server's PHP user. On a Magento server that user can read app/etc/env.php, so treat this as a full store compromise risk, not a minor bug.
Who is at risk from php2shell?
php.net says all PHP installations serving web requests, and names PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. It rates the risk highest for mod_php, where there is a demonstrated exploit in which an unauthenticated request triggers the attack before any application code runs. That last part matters: a WAF rule in Magento or a WordPress security plugin never gets a chance to see the request.
For PHP-FPM, which most Magento stores use, the OOM advisory says source analysis suggests it is susceptible but no complete exploit has been shown. The stale state advisory says the session upload progress path was validated against both mod_php and PHP-FPM. So FPM users are not off the hook.
The CLI used only for cron and bin/magento does not serve web requests, but patch it anyway. It usually comes from the same packages and costs nothing extra.
Before you patch, find every PHP on the server. Most boxes run more than one, and php -v shows only one of them. I wrote up how I did that on my own VPS in how to find every PHP version running on your server.
How do I install the PHP security update on my server?
Linux distributions and LTS vendors received the patches in advance, according to php.net, so the normal route is your distro or vendor package. This is the order I patch in: internet-facing web PHP first, then CLI, then dev and staging copies.
Debian and Ubuntu packages (including PPA builds, and control panels like CloudPanel that install PHP as system packages):
sudo apt-get update
apt list --upgradable 2>/dev/null | grep -i php
sudo apt-get install --only-upgrade 'php8.4*'
sudo systemctl restart php8.4-fpm
Repeat the install and restart for each version you actually use. Run apt-get update first, or apt will happily tell you nothing is pending. If your control panel manages PHP through its own repo or update button, use that, then check the result with the version commands further down.
RHEL, AlmaLinux and Rocky: sudo dnf upgrade 'php*', then restart php-fpm or httpd.
Apache with mod_php: PHP lives inside Apache, so after the package update restart Apache itself (sudo systemctl restart apache2 or httpd). Given that php.net rates mod_php as the highest risk, this is the box I would do first.
Docker: host packages do nothing for a container. My own store runs PHP in a container built from the official php:8.4-fpm image, so for it the job is to pull the rebuilt base image, rebuild, and recreate the container. The full steps are in patching PHP inside a Docker container.
Windows: php.net has Windows source and binaries for all four releases on its downloads page. Swap the build, then restart IIS or whatever runs php-cgi.
remirepo users: php.net says the volunteer-run rpms.remirepo.net will not have updates on release day and urges people to switch to distribution packages or build from source so they can patch straight away. If remi is your only source, plan for that.
What if I am still on PHP 8.1, 8.0 or 7.4?
php.net no longer ships releases for PHP 8.1 and older. Huntress reported that versions as old as PHP 5 may be affected, though that is not confirmed. You have three options.
- Vendor backport. Some distributions and paid LTS vendors backport fixes. Ask yours, and get a package version you can check, not just a yes.
- Minimal source backports. Because of the severity, the PHP security team published minimal source backports for PHP 7.4, 8.0 and 8.1 as branches in the php-src repository. Useful if you build from source. Not a long-term plan.
- Upgrade. This is my real advice. An old PHP that needed an emergency backport this time will not get one next time.
If an old version is installed but nothing uses it, switch it off. On my own VPS (Ubuntu 24.04 with CloudPanel), PHP-FPM 7.1 to 8.5 were all running. I confirmed nothing used the 7.1 to 8.1 pools and disabled them with systemctl so they cannot be hit. Here is how in disabling end-of-life PHP versions on a server.
Can I mitigate php2shell without updating?
Partly, and only as a stopgap. php.net is clear that these measures reduce exposure to specific attack paths but do not make an installation safe. Here is what the advisory lists.
For CVE-2026-109618 (OOM corruption):
- Set
memory_limit=-1in a way applications cannot override, such asphp_admin_valuein the FPM pool or Apache config, and check nothing sets a finite limit back. php.net notes an underlying allocation failure can still reach the bug. - Set a low
post_max_size:8Mif the app needs no uploads,32Mif it does, and keepupload_max_filesizebelow it. Consider limits at the web server or proxy for decoded request size, field count, multipart part count, header count and nesting depth, including requests without a usable Content-Length. - Use a container or cgroup memory limit as an availability boundary, ideally killing only the affected worker. Do not use
RLIMIT_ASorRLIMIT_DATA, because they can cause the exact allocation failure you are trying to avoid.
For CVE-2026-109619 (stale global state):
- Set
session.upload_progress.enabled=0in php.ini, the FPM pool or server config, and restart every worker. Not throughini_set()or.user.ini. This blocks the confirmed session paths only. - On PHP 8.5, set
fatal_error_backtraces=0and restart every worker. This blocks the confirmed backtrace path only. - Remove invalid or deprecated per-request settings that print diagnostics before startup. Hiding them with
error_reporting,display_errorsor@does not help. - Fix fatal errors and timeouts an attacker can trigger, including in upload and import handling.
; FPM pool file, e.g. /etc/php/8.4/fpm/pool.d/www.conf
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 16M
php_admin_value[session.upload_progress.enabled] = 0
; PHP 8.5 only
php_admin_value[fatal_error_backtraces] = 0
On a Magento store, test this before trusting it. Admin product imports and image uploads can hit a 32M post limit, and memory_limit=-1 on a busy box means a runaway request can eat RAM, which is why the cgroup limit is part of the advice. The stale state advisory also suggests keeping session upload progress off after patching if you do not need it, and that one I would keep.
How do I check that the update actually worked?
An updated package is not a patched server. The old binary keeps running until each worker restarts. Check every PHP, not one:
# CLI
php -v
# every FPM binary on the host
for b in /usr/sbin/php-fpm*; do echo "$b"; "$b" -v | head -1; done
# running FPM services and when they last started
systemctl list-units 'php*-fpm*' --state=running
systemctl show php8.4-fpm -p ActiveEnterTimestamp
# every container
for c in $(docker ps --format '{{.Names}}'); do
echo "$c"; docker exec "$c" php -v 2>/dev/null | head -1
done
You want 8.5.12, 8.4.27, 8.3.36 or 8.2.35 everywhere (or your vendor's patched build string), and a service start time after the package install. For mod_php, check Apache's start time the same way.
Then ask the other question: did anything get in before you patched? Huntress suggests watching for PHP workers spawning shells, interpreters or download tools. Before this release I checked my own VPS for exactly that: no PHP worker spawning shells, nothing odd in the access logs, no PHP files in upload folders. The full routine is in checking a Magento server for PHP RCE compromise.
What does php2shell mean for Magento stores?
Magento runs on whatever PHP your server gives it, so the patch is a server job, not a composer update. What you should check is that you are on a PHP your Magento line supports, so the update is a minor bump and not a migration.
- Magento 2.4.9: Adobe's release notes say PHP 8.5 is fully supported and PHP 8.4 is allowed for upgrade purposes only, not recommended for production. PHP 8.2 and 8.3 are no longer supported. So 2.4.9 stores should end up on 8.5.12.
- Magento 2.4.8: PHP 8.3 and 8.4, so 8.3.36 or 8.4.27.
- Magento 2.4.7: PHP 8.2 and 8.3. If you are on 8.2, take 8.2.35 now and plan the move off 8.2 before 31 December 2026.
- Magento 2.4.6: PHP 8.1 and 8.2. If you are on 8.1, move to 8.2.35 now, which 2.4.6 supports.
- Magento 2.4.5 and 2.4.4: Adobe lists PHP 8.1 only, and 8.1 gets no php.net release. This is the group in the most trouble, and the honest fix is a Magento and PHP upgrade.
Remember Magento cron runs on CLI PHP, often with a full path in the crontab, while the storefront runs on FPM or a container. Patch both and restart both. And PHP is only half of it: Adobe also shipped Magento fixes this month, covered in the APSB26-153 October 2026 security patch.
php2shell timeline
- 20 October 2026, morning: a Hacker News post claimed two critical PHP vulnerabilities were coming. It was taken down, but screenshots spread. Huntress reported that watchTowr confirmed the bugs were real and that the original embargo had been a day later.
- 20 October 2026: php.net posted advance notice of a release for 21 October at 14:00 UTC, fixing two critical vulnerabilities rated CVSS v4.0 9.2, and reserved the right to release earlier.
- 21 October 2026: the two GitHub advisories went public at 13:34 UTC, ahead of the 14:00 UTC slot, and php.net released 8.5.12, 8.4.27, 8.3.36 and 8.2.35 the same day.
As of 20 October Huntress said it had not seen exploitation in the wild. I would not count on that lasting now that the advisories describe the bugs in detail.
If you run a Magento or PHP server and want someone to do the inventory, patching and compromise check for you, hire me or message me on WhatsApp. If the store is already misbehaving, use urgent Magento bug fixing.
FAQ
What is php2shell?
php2shell is the informal name for CVE-2026-109618 and CVE-2026-109619, two critical PHP vulnerabilities rated CVSS v4.0 9.2 that can allow unauthenticated remote code execution. They were fixed on 21 October 2026.
Which PHP version should I update to?
Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, matching the branch you run. Every earlier version on those branches is affected.
Is PHP-FPM affected, or only mod_php?
Both. php.net lists PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed. mod_php has the highest risk and a demonstrated exploit, and the session upload progress path was validated against PHP-FPM too.
Is there a fix for PHP 8.1, 8.0 or 7.4?
Not a php.net release. Some distributions and LTS vendors backport fixes, and the PHP security team published minimal source backports for 7.4, 8.0 and 8.1. Upgrading to a supported PHP is the better fix.
Can I use memory_limit=-1 instead of updating?
No. php.net lists it as a measure that reduces exposure to one attack path, and says an underlying allocation failure can still reach the bug. None of the listed mitigations make an install safe.
Does updating host PHP packages patch my Docker containers?
No. Each container has its own PHP from its image. Pull the rebuilt base image, rebuild, recreate the container and check php -v inside it.
Do I need to restart PHP after updating?
Yes. Running workers keep the old code in memory. Restart every PHP-FPM service, Apache if you use mod_php, and every container, then confirm the version and service start time.
Which PHP should Magento 2.4.9 use?
Adobe's release notes say PHP 8.5 is fully supported on 2.4.9 and PHP 8.4 is allowed for upgrade purposes only, not production. So 2.4.9 stores should run PHP 8.5.12.
Why is remirepo not updated?
php.net said on 21 October that the volunteer-run rpms.remirepo.net would not have updates that day, and urged users to switch to distribution packages or build from source so they can patch at once.