When a customer asks whether their cPanel server is safe from PHP2Shell, the answer depends on more than one package set. The version php -v prints will not settle it either. cPanel’s EasyApache 4 ships its own PHP builds, CloudLinux replaces them with backports that keep the old version, and CloudLinux’s PHP Selector adds a third set under /opt/alt. Each one got its fix for CVE-2026-109618 and CVE-2026-109619 from a different team, on a different day, through a different command.
This guide patches PHP2Shell on cPanel and WHM servers across all three: finding which PHP builds the server carries, updating the EasyApache packages, proving the backports with their changelogs, patching CloudLinux alt-php, and the Imunify360 rules and NCSC mitigation script that cover the gap. We didn’t have a licensed cPanel server in the lab for this one, so this update re-checks every command against cPanel’s support article and CloudLinux’s status page as they stood on 22 October 2026, cross-checked against the package versions admins reported on cPanel’s own forum.
Every command here is for cPanel on AlmaLinux, Rocky Linux or CloudLinux, which use rpm with yum or dnf. On cPanel for Ubuntu, and on CloudLinux for Ubuntu, the packages update through apt instead (CloudLinux gives apt-get update && apt-get upgrade for its Ubuntu alt-php builds, which upgrades every package on the system), and the rpm changelog checks below do not apply there.
Knowing which PHP builds cPanel runs
A typical cPanel server runs several PHP versions at once, because MultiPHP lets every account pick its own. Before you update anything, list what is installed, because each line below is a separate thing to patch and a cPanel server on CloudLinux carries all three:
- EasyApache 4 PHP:
ea-phpXXpackages such asea-php81orea-php84, under/opt/cpanel/ea-phpXX - CloudLinux PHP Selector:
alt-phpbuilds, under/opt/alt/phpXX - cPanel’s internal PHP:
cpanel-php, which runs WHM and cPanel themselves
The quickest inventory of the EasyApache side comes from rpm, and cPanel’s staff recommend it over php -v:
rpm -qa 'ea-php*-php-cli' | sort
To see which version each site actually uses, ask WHM’s API. The first call lists installed versions, the second maps every virtual host to its PHP, and any version with even one site on it has to be patched before you can call the server safe:
whmapi1 php_get_installed_versions
whmapi1 php_get_vhost_versions
Keep that output, because it is the list you will check off after the update.
Patching PHP2Shell on cPanel ea-php packages
cPanel published the fix in EasyApache 4 change log 25.91 on 21 October 2026. Supported branches moved to the new upstream versions, and the three end-of-life branches got backports that keep their old version numbers. That split decides how you verify each one later, so note which branches your accounts use. These are the releases cPanel’s support article lists as patched:
| Package | Patched release | Fix type |
|---|---|---|
| ea-php85 | 8.5.12 | upstream release |
| ea-php84 | 8.4.27 | upstream release |
| ea-php83 | 8.3.36 | upstream release |
| ea-php82 | 8.2.35 | upstream release |
| ea-php81 | 8.1.34-5 | backport (EA-13611) |
| ea-php80 | 8.0.30-12 | backport (EA-13612) |
| ea-php74 | 7.4.33-19 | backport (EA-13613) |
| ea-php73 and older (cPanel builds) | no fix | TuxCare ELS for PHP |
| ea-php52 to ea-php85 (CloudLinux builds) | see the changelog check | CloudLinux backport |
The packages arrive through cPanel’s normal update system. On supported cPanel versions (110, 134 and later), WHM’s Security Updates option (the SECURITY_UPDATES key in /etc/cpupdate.conf) applies security releases within an hour by default, and cPanel’s staff said on the forum this release would reach servers within an hour. The rollout was staggered, though, so a server can sit on the old build well past that hour, and the exploit details are already public. cPanel’s own instructions refresh the package cache and then run the RPM updater straight away:
yum clean all && yum makecache
/scripts/rpmup
Before you trust a single command, read one forum report that caught several admins out. Admins who ran /scripts/upcp --security found it updated cPanel’s internal PHP but not the EasyApache packages, and they needed a plain dnf update as well. Updating the EasyApache PHP packages by name avoids that ambiguity, so we use it on every server even when automatic updates are on. On AlmaLinux, Rocky Linux and CloudLinux 8, 9 and 10, that is dnf:
dnf clean all && dnf upgrade 'ea-php*'
CentOS 7 and CloudLinux 7 have no dnf, and cPanel 110, one of the four patched branches, still runs there. Use yum on those servers:
yum clean all && yum update 'ea-php*'
Servers running Imunify360’s Hardened PHP on AlmaLinux or Rocky Linux get CloudLinux-built ea-php packages from the imunify360-ea-php-hardened repository, even without CloudLinux itself. Admins on the forum updated them with dnf update "ea*" --enablerepo=imunify360-ea-php-hardened --refresh, and those builds need the CloudLinux changelog check further down, not a version check.
Then restart Apache and every PHP-FPM pool cPanel manages, so no worker keeps the old library in memory. CloudLinux’s instructions for the same update name these two scripts:
/scripts/restartsrv_httpd
/scripts/restartsrv_apache_php_fpm
cPanel rolled the packages out in stages, so two servers updated an hour apart can see different results. If a server still shows the old release, refresh the cache and run the update again before assuming anything is wrong.
Checking the changelog, not php -v
Version numbers only prove the fix on the upstream-numbered branches. An ea-php83 that reports 8.3.36 is patched. An ea-php81 that reports 8.1.34 might or might not be, because the backport keeps the version string. cPanel’s support article gives the check that settles it:
rpm -q --changelog ea-php81-php-cli | grep -m1 CVE-2026-109618
The full rpm changelog puts the release on a header line and the fix on the line below it, and grep -m1 prints only the second one. A patched ea-php81 prints this line, which admins quoted on the forum:
- EA-13611: Backport fix for CVE-2026-109618 and CVE-2026-109619
Run the same check for ea-php80 and ea-php74. On the upstream-numbered branches the matching line names the version bump instead, such as - EA-13608: Update ea-php84 from v8.4.26 to v8.4.27 (CVE-2026-109618, CVE-2026-109619). Empty output means the package is still vulnerable, so you run the update again and repeat the check until the line appears.
CloudLinux servers need this check for every branch. CloudLinux rebuilds the EasyApache packages itself and ships the fix as a backport for every version from ea-php52 to ea-php85, so a patched CloudLinux ea-php84 still reports 8.4.26 (release 8.4.26-2.elX.cloudlinux.1), and its ea-php56 to ea-php73 are patched too, unlike cPanel’s own builds. Admins on cPanel’s forum reported customers asking why WordPress still showed 8.4.26 after the update. CloudLinux gives this form of the check, which matches either CVE:
rpm -q ea-php71-php-cli --changelog | grep -E 'CVE-2026-(109618|109619)'
CloudLinux also notes that security-only updates such as yum --security don’t list these packages, because the advisory metadata isn’t published yet, so use the plain update commands above and restart Apache and PHP-FPM afterwards.
Patching CloudLinux alt-php
The PHP Selector builds under /opt/alt are separate packages from EasyApache, and accounts on a selector version stay vulnerable after every ea-php package is fixed. The alt-php picture changed twice overnight. Since 22 October at 00:07 UTC, CloudLinux’s status page puts every fixed alt-php build in the regular repositories:
- CloudLinux 7, 8 and 9: alt-php 5.2 to 5.6, 7.0 to 7.4 and 8.0 to 8.5, from the CloudLinux stable repositories
- CloudLinux 10: alt-php 5.3 to 8.5 from the TuxCare ELS alt-php repository, which is its normal source, and alt-php 5.2 from the CloudLinux repositories
- CloudLinux 6: not confirmed yet
A regular update now installs the fix everywhere except CloudLinux 6. CloudLinux 7 uses yum:
yum clean all && yum update 'alt-php*'
CloudLinux 8, 9 and 10 use dnf, and on 10 the same command pulls from both repositories:
dnf clean all && dnf upgrade 'alt-php*'
If you followed CloudLinux’s earlier advice on 21 October and added the ELS alt-php repository to a CloudLinux 7, 8 or 9 server, that server already has the fix. CloudLinux says you can disable the repository now, with yum-config-manager --disable php-els on 7 or dnf config-manager --set-disabled php-els on 8 and 9, then run the regular update again. Leave it alone on CloudLinux 10, which gets alt-php from it.
Restart every PHP service afterwards (Apache, PHP-FPM or LiteSpeed), because a running worker keeps the old code in memory even after the changelog check passes. Then prove each version with its changelog:
rpm -q --changelog alt-php82-common | grep -E 'CVE-2026-(109618|109619)'
Like CloudLinux’s ea-php builds, alt-php keeps the old version number, so the changelog line is the only proof. Run the changelog check for every alt-php version an account uses, not only the one you updated first, because each version is its own package and they do not update as a set. CloudLinux’s PHP2Shell post keeps the current status for each release, CloudLinux 6 included.
Updating cPanel’s own PHP
WHM and the cPanel interface run on cPanel’s internal PHP, which updates with cPanel itself rather than with EasyApache. cPanel’s release notes list PHP 8.4.27 in versions 138.0.18, 136.0.50 and 134.0.66, and a backported 8.1.34 in 110.0.153. WP Squared servers get the fix in 11.138.1.17. Check which build the server runs, then update cPanel if it’s older:
/usr/local/cpanel/cpanel -V
/scripts/upcp
The internal PHP package itself is the direct proof. Query it by name, using cpanel-php81 on version 110:
rpm -q cpanel-php84
A patched 134, 136 or 138 server reports 8.4.27 there, and a patched 110 server reports cpanel-php81 at release 8.1.34-2 or later. The version alone proves nothing on 110, because the unpatched package was already 8.1.34. One admin on version 132 reported cpanel-php84 stuck at 8.4.21 with no update offered, which points at the cPanel version being out of support rather than at the PHP package. If the server is not on one of these four branches, plan the cPanel upgrade, not just a PHP one.
Adding the Imunify360 rules
Imunify360 shipped three WAF rulesets on release day, and they buy time on servers where a package can’t be installed immediately. They only reach servers with the Imunify360 WAF enabled; with the WAF off, CloudLinux’s own table lists no coverage. Each one widened the coverage:
- 8.83: blocks the publicly circulating exploit request, but does not run on LiteSpeed
- 8.84: blocks the public exploit tool on every web server, LiteSpeed included
- 8.85: blocks further variants
Treat them as a partial cover. The blocking rules target the session upload progress path the public exploit uses, which is CVE-2026-109619. CVE-2026-109618’s out-of-memory path doesn’t need a session, and CloudLinux says no rule blocks it yet. On cPanel with Apache, check which ruleset the server has and force an update if it’s older than 8.85:
cat /etc/apache2/conf.d/modsec_vendor_configs/imunify360-full-apache/VERSION
imunify360-agent update --force modsec-rules
That VERSION path is for Apache. LiteSpeed servers keep the file elsewhere, and CloudLinux’s post links Imunify360’s ruleset version article for those paths. Watch for one side effect, too. CloudLinux warns that the 8.84 rule can also stop a legitimate upload form hosted on another domain, or an upload from a browser that strips the Referer header, so a customer report of broken uploads after release day is worth checking against the Imunify360 log first. ImunifyAV and ImunifyAV+ have no WAF and no coverage.
Applying NCSC-NL’s mitigation script
The Dutch NCSC published a cPanel mitigation script in its php2shell repository for servers that can’t be patched yet. It is careful by design: it never edits php.ini, and it does a dry run unless you add --apply. Download it and read it before anything else:
curl -fsSLO https://raw.githubusercontent.com/NCSC-NL/php2shell/main/detection_mitigation/cpanel/php2shell-mitigate.sh
less php2shell-mitigate.sh
Once you have read it, run it without options for the dry run, which prints what it would change:
sudo bash php2shell-mitigate.sh
Then apply it for real. Note that --apply restarts Apache and every running ea-php FPM pool unless you also pass --no-restart, so run it in a window where a restart is acceptable:
sudo bash php2shell-mitigate.sh --apply
With --apply, it writes a drop-in for every /opt/cpanel/ea-php* version that loads last, so it overrides the MultiPHP INI Editor:
session.upload_progress.enabled = 0post_max_sizeandupload_max_filesizecapped at 32M, or 8M with--post-max 8Mon servers whose sites take no uploads (the flag caps every ea-php version on the server), never raised above the current valuememory_limit = -1, only when you pass--memory-unlimited
One more thing catches people out: it only touches /opt/cpanel/ea-php*, so accounts on CloudLinux’s PHP Selector builds under /opt/alt get no mitigation from it at all.
The script also reports per-account overrides in .htaccess, .user.ini and php.ini files under /home without changing them, and warns about Apache’s RLimitMEM, which sets the kind of memory rlimit PHP’s advisory says can trigger the bug. --rollback --apply removes everything it wrote. Treat it as a stopgap: its own header says “ONLY UPDATING IS A COMPLETE FIX”. Our PHP2Shell mitigation guide explains what each of those settings stops and what it doesn’t.
Handling PHP 7.3 and older
On AlmaLinux and Rocky Linux, cPanel’s own ea-php56 to ea-php73 got no fix. cPanel’s staff confirmed on the forum that rebuilds of those packages only bumped the build number and carry no security changes, and cPanel’s support article points those servers at TuxCare’s Extended Lifecycle Support for PHP. CloudLinux servers are the exception: CloudLinux released patched ea-php52 to ea-php73 builds (ea-php73 is 7.3.33-15.elX.cloudlinux.18, for example), so the changelog check above proves them like any other branch. Admins on Imunify360 Hardened PHP report the same CloudLinux builds on AlmaLinux and Rocky Linux; the changelog check settles it either way.
On a cPanel-built server, the practical move is to retire the old versions:
- Find every account on them with
whmapi1 php_get_vhost_versions. - Move each account to a patched branch in WHM’s MultiPHP Manager.
- Confirm no virtual host still uses the old version.
- Remove the old package in WHM’s EasyApache 4 interface (Customize, then the PHP Versions step), so nobody can switch back.
Do step 3 before step 4, so no site is left pointing at a PHP version you have just removed.
Keeping the server patched
The slow part of this release was not the update, it was noticing it. A few habits make the next PHP advisory a non-event for a small hosting team:
- Leave Security Updates on in WHM’s Update Preferences, so security releases install within the hour.
- Subscribe to the EasyApache 4 change log, where cPanel lists every ea-php fix and its case number.
- On CloudLinux, check the CloudLinux status page as well, because its packages ship on their own schedule.
- Run the changelog check after every PHP security release, because the version string will mislead you on backports.
For a cross-check that covers every PHP binary on the server, including /opt/cpanel and /opt/alt builds, the PHP2Shell checker runs the version and changelog tests in one pass. If you also run DirectAdmin servers, the DirectAdmin patch notes cover CustomBuild’s version of the same fix, and the multiple PHP versions on cPanel guide shows the MultiPHP Manager screens for moving accounts between versions.