PHP2Shell Patch Guide: Upgrading to PHP 8.2.35, 8.3.36, 8.4.27 and 8.5.12 on cPanel, Plesk, Ubuntu, RHEL and Docker


November 1, 2026

A patched PHP package that has not restarted its workers is still running vulnerable code. That is the detail most upgrade guides do not mention — and it is the most common reason PHP2Shell (CVE-2026-109618) continues to trigger on servers whose administrators believe the problem is already fixed.

This runbook covers the complete php2shell patch process for every major environment: cPanel/WHM with EasyApache 4 and MultiPHP, Plesk, Ubuntu/Debian, RHEL/Alma/Rocky Linux, and Docker. It also covers what to do if you cannot patch right now, and the SimpleXML regression in PHP 8.4.27 and 8.5.12 that you need to test for before promoting either version to production.

If you have not yet confirmed which PHP version your server runs, is my website vulnerable to PHP2Shell takes about five minutes and does not require developer access.

Key takeaways

  • Patched releases: PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12. Any earlier release in those branches is vulnerable to CVE-2026-109618 and CVE-2026-109619. [1]
  • The step most teams miss: After upgrading packages, you must restart PHP-FPM, Apache, or LiteSpeed — whichever PHP process handler your server uses. Running workers keep the old binary in memory until they are restarted.
  • SimpleXML regression: PHP 8.4.27 and 8.5.12 introduce a regression in SimpleXML processing (php-src issue #24488). [2] Test XML-dependent features in staging before promoting these versions to production. PHP 8.3.36 patches both CVEs without this regression. 
  • Interim mitigations exist but reduce exposure only — they do not close the vulnerability. See the mitigation table below.
  • No official patch for PHP 7.x. Servers on PHP 7.4 or older have no upstream fix. See end-of-life PHP options for your choices.

Patched? Prove it. Upgrading the package is step one. A PHP Scan confirms the fix is actually running — not just installed. Verify my patch →

How do I patch PHP2Shell?

Upgrade to PHP 8.2.35, 8.3.36, 8.4.27, or 8.5.12 using your environment’s package manager or control panel, then restart every PHP worker process — PHP-FPM, Apache, or LiteSpeed — because running processes keep the old binary in memory until explicitly restarted. Confirm the active version with php –version after the restart.

Before you start: backup and staging

No patch goes into production without a tested rollback path. Before touching PHP on any live server, complete these steps:

  1. Take a full snapshot — a VM snapshot or AMI, restores faster than a file-level backup alone.
  2. Back up your database — an application that breaks after a PHP upgrade is far harder to debug without a clean database baseline.
  3. Test on staging first — particularly important if you are upgrading to PHP 8.4.27 or 8.5.12, which carry the SimpleXML regression described below.
  4. Record your current PHP version — run php –version and note the exact output. You will need it to confirm the upgrade succeeded and to plan a rollback if required.
  5. Know your rollback path — each platform section below includes the rollback approach for that environment.

For managed WordPress hosting, cPanel-hosted shared accounts, or other environments not covered here, check whether your host has published a specific advisory. Many managed hosting providers began rolling out patched PHP packages within hours of the official release. 

Patch on cPanel/WHM (EasyApache 4, MultiPHP)

cPanel/WHM manages PHP through EasyApache 4 (EA4). Each PHP branch is a separate EA4 package, so updating PHP 8.3.x to 8.3.36 updates an existing package rather than switching branches.

Via the WHM interface (recommended):

  1. Log in to WHM as root.
  2. Navigate to Software → EasyApache 4.
  3. Click Customize on the currently installed profile.
  4. Under PHP Versions, confirm the EA4 package for your active branch (for example, ea-php83) is selected.
  5. Click Review, then Provision to install available updates.

WHM will pull the latest available ea-php packages.

Via the command line:

# Update all installed EA4 PHP packages to the latest available version:

yum update ea-php* -y

 

# Or target a specific branch:

yum update ea-php83 ea-php83-php ea-php83-php-fpm -y

Restart Apache and PHP-FPM (required):

/scripts/restartsrv_apache

/scripts/restartsrv_apache_php_fpm

MultiPHP environments: If you serve multiple domains on different PHP versions, open WHM → Software → MultiPHP Manager and confirm each domain’s assigned version is a patched release. The yum update ea-php* command above updates all installed EA4 PHP branches simultaneously.

Rollback: Re-provision your previous EA4 profile, or downgrade the specific package: yum downgrade ea-php83-8.3.<previous_version>.

Patch on Plesk

Plesk includes its own PHP version manager, and the recommended path is through the Plesk installer to keep PHP under Plesk’s management layer.

Via the Plesk UI:

  1. Log in to Plesk as administrator.
  2. Go to Tools & Settings → Updates and Upgrades.
  3. Click Install or Upgrade Components.
  4. Locate the PHP 8.2, 8.3, 8.4, or 8.5 entry and install the latest available version.

Via the command line:

# Upgrade to the latest available PHP 8.3 component:

plesk installer –select-release-current \

  –install-component php8.3

 

# Repeat for each active PHP branch on the server.

Restart PHP-FPM:

plesk svc –restart php-fpm

If Plesk runs per-domain PHP-FPM service handlers, also check Domains → [your domain] → PHP Settings to confirm which handler each domain uses and restart accordingly.

Rollback: Re-run the Plesk installer with the previous version number, or restore from your pre-patch server snapshot.

Patch on Ubuntu/Debian

Ubuntu and Debian ship PHP through their own repositories, which may trail the upstream PHP release by several days. For time-sensitive security updates, the ondrej/php PPA (Ubuntu) and deb.sury.org (Debian) typically carry patched releases sooner.

Check your current PHP source:

php –version

apt-cache policy php8.3   # shows which repository provides the package

Upgrade using apt:

sudo apt update

sudo apt install –only-upgrade php8.3 php8.3-fpm php8.3-cli

Replace php8.3 with your active branch (php8.2, php8.4, or php8.5).

If you use the ondrej/php PPA and it is not already configured:

sudo add-apt-repository ppa:ondrej/php

sudo apt update

sudo apt upgrade php8.3

Restart PHP-FPM:

sudo systemctl restart php8.3-fpm

For Apache mod_php configurations (less common on Ubuntu 22.04 and later):

sudo systemctl restart apache2

Verify:

php8.3 -v

Rollback: Pin the previous version with sudo apt-mark hold php8.3 before the upgrade, so you can unhold and downgrade if needed.

Patch on RHEL/Alma/Rocky

Default AppStream modules on RHEL-family systems often ship older PHP versions. For PHP 8.2, 8.3, 8.4, or 8.5, the Remi repository provides current upstream packages.

Update via dnf (if Remi is already configured):

# Select the correct Remi module stream for your target branch:

sudo dnf module reset php

sudo dnf module enable php:remi-8.3

 

# Update PHP and PHP-FPM:

sudo dnf update php php-fpm -y

Replace remi-8.3 with remi-8.2, remi-8.4, or remi-8.5 as required.

If the Remi repository is not yet configured (RHEL 9 / AlmaLinux 9 / Rocky 9):

sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm

sudo /usr/bin/crb enable

sudo dnf module reset php

sudo dnf module enable php:remi-8.3

sudo dnf install php php-fpm -y

Restart PHP-FPM:

sudo systemctl restart php-fpm

sudo systemctl status php-fpm

Verify:

php –version

Rollback: sudo dnf downgrade php php-fpm returns to the previously installed version, or restore from your pre-patch snapshot.

Patch Docker images

A running container that has not been rebuilt continues to execute the old PHP binary regardless of what is installed on the host. Patching Docker environments means updating the base image in your Dockerfile, rebuilding the image, and redeploying.

Update your Dockerfile:

# Replace your existing php:* tag with a patched version:

FROM php:8.3.36-fpm

# or:

FROM php:8.2.35-apache

# or:

FROM php:8.4.27-cli

Pull, rebuild and redeploy:

# Pull the patched official image:

docker pull php:8.3.36-fpm

 

# Rebuild your application image (–no-cache ensures a clean build):

docker build –no-cache -t myapp:latest .

 

# Docker Compose environments:

docker compose pull

docker compose up -d –force-recreate

 

# Kubernetes:

kubectl rollout restart deployment/my-php-deployment

Confirm the running container is on the patched version:

docker exec my-php-container php -v

For Alpine-based PHP images, check Alpine’s package tracker for patched php8x packages before rebuilding.

Restart PHP workers — the step most teams miss

Package managers update files on disk. They do not stop or restart processes already running in memory. A PHP-FPM pool that started before your upgrade is still executing the old binary until you explicitly restart it.

This is the most common reason PHP2Shell remains exploitable on servers that appear to have already applied the php2shell patch. The installed package shows the new version number; the running process does not reflect it.

Confirm which binary a running PHP-FPM process is using (Linux):

# Find the PHP-FPM master process ID:

cat /run/php/php8.3-fpm.pid

 

# Confirm the binary path that process is using:

ls -la /proc/<PID>/exe

If the symlink still points to the old version’s directory, the restart has not occurred.

Restart commands by environment:

Environment Restart command
Ubuntu / Debian — PHP-FPM sudo systemctl restart php8.3-fpm
RHEL / AlmaLinux / Rocky — PHP-FPM sudo systemctl restart php-fpm
cPanel / WHM — Apache /scripts/restartsrv_apache
cPanel / WHM — PHP-FPM /scripts/restartsrv_apache_php_fpm
Plesk — PHP-FPM plesk svc –restart php-fpm
Apache mod_php (general) sudo systemctl restart apache2 or sudo systemctl restart httpd
LiteSpeed sudo /usr/local/lsws/bin/lswsctrl restart
Docker Rebuild image and redeploy container

LiteSpeed note: LiteSpeed runs PHP through its own LSAPI handler. A full restart through the LiteSpeed WebAdmin Console — or the command above — is required. Restarting PHP-FPM alone is not sufficient on LiteSpeed deployments.

Upgraded packages don’t protect you until workers restart.

A PHP Scan checks what your server is actually running — not just what the package manager reports. Use it after every patch wave to confirm the fix is live on every host.

Verify my patch →

Verify the patch worked

After upgrading packages and restarting workers, confirm the fix is active before closing the change ticket.

Post-patch verification checklist:

  • php –version (or php8.3 -v) returns 8.2.35, 8.3.36, 8.4.27, or 8.5.12
  • systemctl status php8.3-fpm shows the service is active and the new binary is referenced
  • A temporary phpinfo() page (on a protected path, deleted immediately after use) shows the correct version under PHP Version and confirms the server API is running the patched build
  • Application smoke test passes — pages load, authenticated flows work, no 500 errors
  • If on PHP 8.4.27 or 8.5.12: XML-parsing features pass your standard test suite (see SimpleXML regression below)
  • A PHP patch verification scan returns a clean result at the network level

Important: A phpinfo() page exposes server configuration to anyone who can reach its URL. Delete it immediately after verification and never commit it to source control.

Can’t patch today? Interim mitigations

If a maintenance freeze, application compatibility issue, or unsupported PHP version is blocking immediate patching, three php.ini settings can reduce your exposure. Note the limitations — these are delay tactics, not fixes.

php.ini setting Directive Limits which CVE Limitation
Disable session upload progress session.upload_progress.enabled = 0 CVE-2026-109618 Reduces the upload-based attack surface; does not close the underlying vulnerability [3]
Cap memory limit memory_limit = 256M (never -1) CVE-2026-109619 Slows memory-leak exploitation; does not prevent it [3]
Disable fatal error backtraces fatal_error_backtraces = 0 CVE-2026-109619 PHP 8.5 only; reduces information disclosure in error output [3]
WAF virtual patch Block payloads matching PHP2Shell patterns CVE-2026-109618 Signature-based; can be bypassed by obfuscated payloads [4]

Apply php.ini changes with a service reload (not a full restart, to minimise downtime):

sudo systemctl reload php8.3-fpm

# or for Apache mod_php:

sudo systemctl reload apache2

For a full discussion of your options when upgrading is not immediately possible — including long-term compensating controls and migration planning — see end-of-life PHP options.

Known issue: SimpleXML regression in PHP 8.4.27 and 8.5.12

PHP 8.4.27 and 8.5.12 patch both CVE-2026-109618 and CVE-2026-109619, but also introduce a regression in SimpleXML processing tracked in the php-src issue tracker as issue #24488. [2]

Applications that parse XML using simplexml_load_string(), simplexml_load_file(), or the SimpleXMLElement class may encounter unexpected behaviour with certain XML inputs after upgrading to these versions. 

Before promoting PHP 8.4.27 or 8.5.12 to production:

  1. Run your test suite in staging with representative XML payloads.
  2. Specifically test RSS/Atom feed parsing, SOAP client integrations, and any XML-based data import or export features.
  3. If the regression affects your application, PHP 8.3.36 is the safer path: it patches both CVEs and does not carry this regression. 

Monitor the php-src GitHub repository (github.com/php/php-src) and the PHP releases page at php.net/releases for a follow-up point release addressing the regression.

Related reading: If you need to determine whether a server was compromised before or during the patch window, detect a web shell covers the specific indicators of compromise for PHP2Shell — including memory artefacts you should capture before restarting services.

 

Use a PHP Scan after each patch wave to confirm nothing was missed — including hosts that were updated by a different team member or an automated process.

Run a post-patch verification scan →

If you manage a distributed or multi-tenant environment, SureShield’s Managed Security Services can help coordinate patch verification across complex infrastructure at scale.

FAQs

Q. Do I need to restart the server after updating PHP?

  1. A full server restart works, but it is not necessary and creates avoidable downtime. What you need to restart is the PHP process handler: PHP-FPM, Apache (for mod_php), or LiteSpeed. Until that process is restarted, it continues running the old PHP binary from memory. The installed package version and the running version will show different numbers until the restart happens.

Q. What if I cannot patch today?

  1. Set session.upload_progress.enabled = 0 and confirm memory_limit is not set to -1 in your php.ini, then reload PHP-FPM or Apache. On PHP 8.5, also set fatal_error_backtraces = 0. A WAF virtual patch targeting PHP2Shell payload patterns adds a further layer of protection. These controls reduce your exposure — they do not eliminate the vulnerability. Plan to complete the patch within days, not weeks.

Q. Does a WAF stop PHP2Shell?

  1. A WAF with rules that target known PHP2Shell payloads can block many exploit attempts, but WAF protection is signature-based and can be bypassed by attackers using obfuscated or modified requests. It is a useful supplemental control, not a substitute for patching. 

Q. Is there a bug in PHP 8.4.27?

  1. PHP 8.4.27 and PHP 8.5.12 include a regression in SimpleXML processing tracked as php-src issue #24488. [2] Applications that use simplexml_load_string(), simplexml_load_file(), or SimpleXMLElement may see unexpected behaviour with certain XML inputs after upgrading. Test in staging first. If the regression affects your application, PHP 8.3.36 patches PHP2Shell without this regression and is the recommended upgrade path until a follow-up point release is available.

Q. How do I verify the PHP2Shell patch worked?

  1. Run php –version from the command line and confirm the output shows 8.2.35, 8.3.36, 8.4.27, or 8.5.12. Then confirm your web server is actually serving the new version — a temporary phpinfo() page (deleted immediately after) or your hosting control panel will show the version in use. For a network-level check that goes beyond the command line, run a PHP patch verification scan to confirm the fix is live from the outside.

About SureShield: SureShield strengthens cybersecurity resilience through governance, risk, compliance (GRC) and cyber maturity solutions, combining technology and advisory expertise to help organisations build sustainable programs aligned with business goals. Based in Atlanta, Georgia. Learn more about SureShield

Leave a comment

Your email address will not be published. Required fields are marked *