Patching PHP2Shell on a Linux server means the PHP process answering requests runs a fixed build, and a clean apt or dnf run does not prove that. Install your vendor's fixed package, restart every worker, pool and container, then check what the serving process actually loaded. CISA lists both CVEs in its Known Exploited Vulnerabilities catalog, so the install comes first and the cleanup second.1
You're affected if: you run a Linux server or container that serves web requests with PHP, and the serving process is not a verified fixed build. Fixed means PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or a vendor build whose advisory covers CVE-2026-109618 and CVE-2026-109619.2 A process that started before the package upgrade may still be running old code. You're not if: the serving process loaded a fixed build after the install. Status as of 4 November 2026.
Patch, restart, verify
- Patch: install the fixed package from your vendor's security repository, or replace the container image.
- Restart: fully restart PHP-FPM and Apache, or replace the container or pod. A reload is not enough.
- Verify: check the process that serves requests, not your shell's
php -v.
The complete PHP2Shell guide covers how both flaws work. This page covers only the install and the proof.
Fixed means three different things on Linux
PHP released 8.5.12, 8.4.27, 8.3.36 and 8.2.35 on 21 October 2026. It issued no release for 8.1 and older, only source-only backports for 7.4, 8.0 and 8.1.2
Distributions split three ways. Debian rebased: bookworm took 8.2.35-1~deb12u1 and trixie took 8.4.27-1~deb13u1, so the version number is the check.3 Ubuntu and AlmaLinux backported: Ubuntu 24.04 still reports PHP 8.3.6, fixed in package release 8.3.6-0ubuntu0.24.04.13, and AlmaLinux 10's php8.4 is 8.4.24-1.el10_2.alma.1.45 The third group, branches nobody fixed, gets its own section below.
A backported build fails any comparison with an upstream number, which is why AlmaLinux tells you to query the package instead of trusting php -v.5 The guide to how to read the package changelog covers the lookup. Mattias Geniar's container tests add a limit: Ubuntu's changelog names the CVE, but Red Hat's rebased php:8.2 and php:8.3 streams say only "rebase", so those need a version comparison.6
| Distro family | Where the fix lives | How to verify |
|---|---|---|
| Debian 12, 13 | Security archive: 8.2.35-1~deb12u1 (DLA-4848-1), 8.4.27-1~deb13u1 (DSA-6574-1)3 | Installed version at or above the fixed version |
| Ubuntu 22.04, 24.04, 26.04 | USN-8948-1: 8.1.2-1ubuntu2.28, 8.3.6-0ubuntu0.24.04.13, 8.5.4-0ubuntu1.54 | Full package release at or above the listed one |
| RHEL 7, 8, 9, 10 | Red Hat lists all four as affected; fixes are in progress.7 Unverified per stream: see below | Match an erratum for your exact stream |
| AlmaLinux 8, 9, 10 | Production repositories since 21 October5 | rpm -q php-common against AlmaLinux's list |
| Rocky Linux 8, 9, 10 | Advisories mirrored on LinuxSecurity.9101112 Unverified on Rocky's own site: see below | Match the RLSA for your stream |
| Amazon Linux, SUSE | Amazon: packages in all regions;13 SUSE: php8 updates such as SUSE-SU-2026:24271-114 | Read the vendor page for your release |
Patching Debian and Ubuntu
Canonical's 21 October post gives these commands for Ubuntu 14.04 through 26.10.4 Start with the full upgrade. It is the vendor-supported path and the one that cannot miss a PHP package:
sudo apt update && sudo apt upgrade
Canonical also lists a PHP-only form:4
sudo apt update && sudo apt install --only-upgrade '?name(^php[0-9.]+$)'
Opinion Treat that one with care. The pattern matches package names like php8.3, and does not obviously match php8.3-fpm, php8.3-cli, libapache2-mod-php8.3 or extension packages. I did not run it. If you use it, list what is installed and what is pending, and name every PHP package that shows up:
apt list --installed 2>/dev/null | grep -i php
apt list --upgradable 2>/dev/null | grep -i php
Canonical says the application using PHP would likely need a restart, and gives sudo systemctl restart apache2 for mod_php, or a reboot.4 Unattended-upgrades installs the fix within 24 hours, but the affected applications still need a restart.4 Ubuntu 22.04 and newer get the fix under standard support. Ubuntu 20.04 and older need Ubuntu Pro, and 16.04 and 14.04 also need the Legacy add-on.4
Debian's tracker lists 8.4.27-1~deb13u1 as the fixed trixie build under DSA-6574-1, and gives no commands. It lists the point-release build 8.4.24-1~deb13u1 as vulnerable, so check that the server pulls from the security archive.3 Servers on ppa:ondrej/php or packages.sury.org take the fix from that repository, not from the Debian or Ubuntu notice.
Patching Red Hat, Rocky and AlmaLinux
RHEL: status unverified per stream
Red Hat's bulletin, last updated 23 October, says some updates are available and more are in progress. It lists RHEL 7 through 10 as affected and names no fixed package builds.7 Red Hat's CVE page did not render its per-package table when I opened it on 4 November, so I cannot confirm which streams have an erratum. A 30 October update from No7 Software of Red Hat's CVE data still showed RHEL 9's php:8.4 stream as affected with no erratum.8 That is a secondary source and may be stale.
Do not read the absence of a confirmed erratum as a fix or as a gap. Open Red Hat's CVE page for your major version and stream, find an erratum number, and install that. Geniar recorded a fixed php 8.4 for RHEL 9 in Remi's repository, a third-party stopgap that changes who supports the package.6
Rocky Linux: seen on a mirror only
I did not reach Rocky's own errata pages. LinuxSecurity's mirrors list RLSA-2026:87072 (Rocky 9, php 8.2.35) and RLSA-2026:87079 (Rocky 9, php 8.3.36), both posted 21 October.910 They also list a Rocky 10 update with php 8.3.36 for the same CVEs, RLSA-2026:87070.11 A Rocky 8 advisory, RLSA-2026:87073, lists CVE-2026-109618, but the mirror's package excerpt shows libzip and apcu, so confirm which php stream it covers.12 I found nothing for Rocky 9 or 10 php 8.4. Check Rocky's errata for your exact stream before relying on any of this.
AlmaLinux
AlmaLinux moved every PHP stream on AlmaLinux 8, 9 and 10 to production at 21:15 UTC on 21 October.5 Its commands:
sudo dnf clean metadata && sudo dnf upgrade 'php*'
sudo systemctl restart php-fpm # AlmaLinux 8 with mod_php: sudo systemctl restart httpd
rpm -q php-common # PHP 8.4 on AlmaLinux 10: rpm -q php8.4-common
Compare the rpm output with the versions in AlmaLinux's post.5 dnf module list php shows the enabled stream. AlmaLinux patched the retired streams (php:7.2, 7.3 and 8.0 on AlmaLinux 8, php:8.1 on AlmaLinux 9) but does not guarantee future fixes, and php:7.2 is still AlmaLinux 8's default.5
Reported CloudLinux said on 22 October that its advisory metadata was not yet published, so security-only updates did not list its fixed packages.15 Run the full dnf upgrade 'php*' above instead.
Restart every worker, pool and container
An upgraded package changes files on disk and tells no running process about it.15
Red Hat's bulletin says a reload is not enough, because existing workers can keep affected state from earlier requests:7
systemctl restart httpd # mod_php, the default on RHEL 7
systemctl restart php-fpm # PHP-FPM, the default on RHEL 8 and later
On Debian and Ubuntu the FPM unit carries the version, for example php8.3-fpm.6 Measured Geniar's container test found that a PHP-FPM reload put the new binary into the master and every worker, while apachectl graceful and apachectl -k restart left Apache on the old libphp until a full stop and start.6 Opinion Restart both anyway: Red Hat's reason concerns worker state, Geniar's test concerns which binary loads, and systemctl restart satisfies both.
Servers with several PHP versions or Software Collections run separate services, so restart each one. dnf needs-restarting -s lists systemd services running files from updated packages (dnf-plugins-core 4.3.1 and later).16
Verify the serving process, not your shell
php -v reports the CLI binary. The web server may load something else.
Red Hat says to verify configuration through a temporary phpinfo() page rather than php -i, which reports the command-line configuration.7 Use the same page to confirm the version the web SAPI reports, and compare it with the package you installed. On backported builds the reported number can look old, so the package release is the final check.
phpinfo() output exposes configuration, file paths, loaded modules and environment values. Put the page behind authentication or an IP allowlist before you request it, never leave it on a public URL, and delete it as soon as you have read the version.
For the loaded binary itself, use standard Linux process inspection. This is not a vendor command, and I did not run it:
# PHP-FPM or CLI-style binary: a "(deleted)" suffix means the file on disk was replaced after the process started
sudo ls -l /proc/<fpm-master-pid>/exe
# mod_php: check the mapped library in an Apache worker
sudo grep -i libphp /proc/<apache-pid>/maps
Treat start time as supporting evidence only. A process that started before the upgrade is a strong warning, but the loaded executable or module decides. Do not call a host fixed until both agree with your vendor's package.
Containers, Kubernetes and arm64 hosts
Red Hat's instruction for containerized deployments is to replace the running container or pod.7 Docker updated its Official Images and Hardened Images and says updating is the only complete mitigation.17 A rebuild must pull the new base, and Docker's --pull build flag always attempts to pull newer images.18 An image pinned to a patch tag stays on the old build until you edit the tag. Server Side Up's v5.0.2 notes tell users to change 8.4.26-fpm-nginx to 8.4.27-fpm-nginx, then verify inside the container:19
docker compose exec php php -v
That reports the container's CLI build, so compare it with the container's start time and the image digest too. The page on patching PHP in containers covers FrankenPHP and platform images, which bundle their own PHP, so host-level apt and dnf change nothing for them.6
cPanel's 26 October summary told administrators to confirm that arm64 hosts run a fixed version, because some repositories published amd64 builds first, and to rebuild container images, CI runners and internal tooling that embed PHP.15 Geniar's 24 October check found packages.sury.org arm64 still serving unfixed 8.3.35 and 8.4.26 builds on several releases.6 AWS cannot update running Lightsail instances in place and asks customers to launch new ones from updated blueprints.13
When your branch has no fix, or you can't patch today
AWS lists PHP 5.4 through 8.1 as affected with no upstream fix.13 Coverage depends on who builds your package: Ubuntu fixed 22.04's php8.1 and, through Ubuntu Pro, releases back to 14.04, and AlmaLinux patched its retired streams.45 Geniar's warning is that a backport fixes this bug and does nothing for the next one, because PHP no longer reviews those branches.6 The page on PHP 8.1 and older covers vendor, third-party and migration options.
Interim settings are not a patch
PHP says only an update is a complete solution. Its interim controls reduce specific attack paths: session.upload_progress.enabled=0, a low post_max_size, and memory_limit=-1 set where applications cannot override it.2 Red Hat says the same: configuration changes may disrupt workloads and are not a substitute for patching, and the memory and request-size changes do not eliminate the CVE-2026-109618 failure.7
memory_limit=-1 removes PHP's own memory ceiling. Do not apply it unless a container or cgroup memory limit is already in place, or one runaway request can exhaust the host. Red Hat also says not to use RLIMIT_AS or RLIMIT_DATA as that boundary, because they trigger the very allocation failure the flaw depends on.7
Apply these settings with php_admin_value in the PHP-FPM pool or Apache configuration, not ini_set() or .user.ini, and restart every worker afterward.7 The guide to the interim setting while you wait covers where to set it and what it breaks.
Reported Geniar's reading of the 8.5.12 source finds a new hard memory limit, set at twice memory_limit for limits up to 1G, that ends the worker with exit code 137, so restore a finite memory_limit after patching if you used -1.6 PHP's 23 October note says the 21 October releases do not fix CVE-2026-115560, so keep session.upload_progress.enabled=0 after patching.2
Patching does not remove a web shell
A fixed build stops new exploitation and does nothing about an earlier one.
CISA added both CVEs to KEV on 26 October, which documents exploitation somewhere, not on your server.1 The timeline at webhosting.today notes that the catalog also covers attempted exploitation, and that no agency or host it cited reported a confirmed compromise.15 Amazon Threat Intelligence recorded an attempt on 17 October, four days before disclosure, so a pre-patch check should reach back before the 21 October release.15 CISA's directive for federal agencies expects a check for compromise before the patch.1
For a server that was reachable before you patched it, the guide to checking for an existing web shell lists what to inspect. Geniar reports that the researchers say the flaws can also leak worker memory, so rotate the secrets that server held.6
How you'd notice
Investigate the patch status if any of these is true. Each is a warning sign, not proof that the patch failed:
- The loaded executable or module on the serving process is marked "(deleted)" or does not belong to the fixed package.
dnf needs-restarting -sstill lists php-fpm or httpd.16- The container image tag or digest matches what you ran before 21 October.
- The CLI version differs from what the web server loads, which AlmaLinux and Wordfence both warn about.515
- The service start time predates the upgrade.
You may have been hit before patching if workers crashed, since Wordfence's lab saw the CVE-2026-109619 proof of concept crash a normal build and run code only on a specially configured one.15 New or modified files under web roots are the other early sign.
Triage: patch, restart and verify first
Do today
- Identify the PHP binary or module that serves requests on each internet-facing host and container, and the package or image that provides it.
- Compare each installed package with your vendor's fixed version: Debian's tracker entry, Ubuntu's USN-8948-1 table, an erratum you confirmed for your Red Hat stream, the Rocky advisory for your stream, or AlmaLinux's list.
- Upgrade the PHP packages from your distribution's security repository with the vendor commands above.
- Rebuild internet-facing container images from a patched base with
--pull, edit pinned patch tags, and redeploy every affected pod. - Restart PHP-FPM, and fully restart Apache for mod_php.
- Verify the web-serving PHP through the running process: loaded binary or module, a restricted temporary
phpinfo()page on the web SAPI, and package release. - Apply interim settings on hosts you cannot patch today, and set
memory_limit=-1only with a container or cgroup memory limit behind it.
Do this week
- Rebuild internal containers, CI runners and internal tooling that embed PHP, and check each arm64 host against the fixed version.
- Inspect servers that were reachable before the patch for web shells, and rotate the secrets they held.
- Restore a finite
memory_limitif you set -1, and keepsession.upload_progress.enabled=0.
Can wait
- Replace PHP 8.1 and older with a supported branch, and plan around PHP 8.2 losing security support on 31 December 2026.2
- Retire third-party backport repositories once the migration is done.
- Re-check Red Hat's CVE page for your RHEL stream, and Rocky's errata, until each lists an erratum you have confirmed.


Comments