psf-php2shell-cpanel-mitigate(8)

Script: /opt/psf-security-patches/php/php2shell-cpanel-mitigate.sh. Tool page: PHP2Shell. Source. With the package installed: man psf-php2shell-cpanel-mitigate.

PHP2Shell mitigation for cPanel EasyApache 4  (v1)

If this software is helpful, consider a donation to our 501c3 nonprofit:
https://privacysafe.foundation

CVE-2026-109618 and CVE-2026-109619 ("PHP2Shell") are fixed by updating PHP
(8.5.12 / 8.4.27 / 8.3.36 / 8.2.35, or a vendor build that names both CVEs in
its changelog). Nothing here replaces that. This script covers the hosts the
Debian tool (php2shell-mitigate.sh) refuses: cPanel servers running
EasyApache 4 PHP (ea-php74 ... ea-php85) under any handler.

It writes ONE drop-in per ea-php version into that version's php.d directory,
named so it sorts after every other file there and therefore wins over
php.ini and the MultiPHP INI Editor. It never edits php.ini. A file in php.d
is read when the process starts, so the web server and any FPM pools must be
restarted; apply does that unless told not to.

What the drop-in sets:
  session.upload_progress.enabled = 0     every version, patched or not:
                                          CVE-2026-115560 is not fixed by the
                                          21 October releases
  fatal_error_backtraces = 0              PHP 8.5, unpatched builds only
  memory_limit = -1                       only with --memory-unlimited, and
                                          only on unpatched builds (PHP's own
                                          protective measure; it trades the RCE
                                          for denial of service, so pair it
                                          with a request body cap)
  post_max_size / upload_max_filesize     only with --post-max / --upload-max;
                                          capped to the smaller of the current
                                          value and your ceiling, never raised

What check reports, besides the above:
  * the PHP handler of each version (from WHM, when whmapi1 is present)
  * whether each version is patched: by version, or because the package
    changelog names both CVEs
  * settings elsewhere that can undo the drop-in: FPM pool entries,
    .user.ini and .htaccess php_value / php_flag lines
  * Apache RLimitMEM / RLimitCPU, which cap processes Apache itself forks
    (CGI, suEXEC, suPHP) and which PHP's advisory warns against as a memory
    limit, because a failed allocation sends PHP down the vulnerable path
  * web server and FPM processes that started before the drop-in changed

Usage:
  ./php2shell-cpanel-mitigate.sh [command] [options]

  check (default)  read-only report, and the file apply would write
  apply            write the drop-in for every version, verify it, restart
  status           what is in place now, and whether workers need a restart
  restore          remove the drop-ins this script wrote
  cleanup          once a version is patched, reduce its drop-in to the one
                   line CVE-2026-115560 still needs (--force to do it for an
                   unpatched version too)

Options:
  --post-max SIZE       cap post_max_size (for example 32M; never raises it)
  --upload-max SIZE     cap upload_max_filesize (default: same as --post-max)
  --memory-unlimited    memory_limit = -1 on unpatched versions (see above)
  --no-restart          write files only; you restart Apache and FPM
  --no-scan             skip the per-directory scan under the home directories
  --force               with cleanup, also reduce unpatched versions
  -h, --help            this text
  -V, --version, version

Exit: check: 0 = every version patched and nothing to review,
      1 = an unpatched version is present, 2 = patched but something to review.
      Other commands: 0 = done, 1 = failed.

Env overrides:
  EA_ROOT=/opt/cpanel                where the ea-php* directories live
  HOME_ROOT=/home                    where per-directory settings are scanned
  CPANEL_SCRIPTS=/scripts            where restartsrv_httpd lives
  APACHE_CONF_DIRS="/etc/apache2/conf /etc/apache2/conf.d"
  SCAN_DEPTH=12                      how deep the home scan looks

check prints the exact plan before apply makes any change, and restore reverts
a drop-in it wrote. Run check first and review the plan before apply.
     PSF_LOCK_WAIT    seconds a run that changes the host waits for another one that is already
                      changing it (default 30), then stops with exit 2; the lock is STATE_DIR/.lock

The Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.

The PrivacySafe Ecosystem

Shop at Ivy Cyber

Ivy Cyber offers PrivacySafe products and services in the USA and has partnerships with 3NSoft in Canada and Kuip Limited in the European Union. Enterprise services and consulting are available at ivycyber.com

PrivacySafe Foundation is a 501(c)(3) nonprofit public charity that supports the development of the PrivacySafe applications, along with the components they rely upon: 3NWeb protocols, filesystem, documentation, and reference implementations.

PrivacySafe Foundation

Donations to PrivacySafe Foundation support education, research, documentation, and public code. Purchases from Ivy Cyber support PrivacySafe products, services, hosting, and technical support. Together, we're building a better web.