Skip to content

Cybersecurity

PHP2Shell Fix for Old and EOL PHP Versions (7.4, 8.0, 8.1)

How to fix PHP2Shell (CVE-2026-109618, CVE-2026-109619) and the new CVE-2026-115560 on end-of-life PHP, what each workaround covers and what it breaks.

By Intelvue Engineering · Updated · 6 min read

Alert: patching is the fix. Update to a supported, official PHP release (8.2.35, 8.3.36, 8.4.27 or 8.5.12 or newer) from php.net or your operating system's packages. The workarounds below reduce risk on old and end-of-life (EOL) PHP while you upgrade. They are not a substitute for running supported PHP.

The short answer: if you are on PHP 7.4, 8.0 or 8.1, install your vendor's patched PHP package (the official backport), set session.upload_progress.enabled = Off, restart PHP, and plan an upgrade to PHP 8.2 or later. On PHP 7.3 or older there is no fix: restrict access to the server and block risky upload requests until you upgrade.

On 21 October 2026, PHP fixed two critical remote code execution flaws known as PHP2Shell (our overview). Two days later, PHP disclosed a related flaw, CVE-2026-115560, which has no fix yet but is blocked by the same setting. This guide is for the many teams that cannot jump to a supported PHP version overnight.

Why this matters for old PHP

A large part of the web still runs unsupported PHP. In August 2026, W3Techs reported about 37% of PHP websites on PHP 7 or older, all past end of life. Add sites on PHP 8.0 and 8.1, which are also EOL, and roughly 4 in 10 PHP sites get no official release for PHP2Shell.

What each measure covers (and breaks)

Measure CVE-2026-109618 CVE-2026-109619 CVE-2026-115560 What it breaks
Supported PHP update (8.2+) Fixed Fixed Not yet (next release) Nothing expected
Vendor backport for 7.4, 8.0, 8.1 Fixed Fixed Not covered Upload progress bars; harsher out-of-memory exits
session.upload_progress.enabled = Off No Partial Blocks the known path Session-based upload progress bars
Block multipart/form-data on routes that don't need uploads Blocks known triggers Blocks known triggers Reduces exposure File uploads and file forms on blocked routes
WAF managed rules (e.g. Cloudflare) Partial Partial Partial Rare false positives
Restrict access or take offline Full Full Full Public access

Every known PHP2Shell trigger so far is a multipart/form-data request (Sansec), which is why upload-related controls help while you patch.

Step-by-step fix for EOL PHP

1. Find every PHP version and how it runs

php -v                         # CLI version
ls /etc/php/ /opt/remi/ 2>/dev/null   # multiple versions side by side
systemctl list-units '*php*fpm*'      # FPM pools in use

Check each site's PHP-FPM pool or Apache mod_php module. The CLI version is often not the one serving traffic.

2. Install the patched package for your branch

PHP published "minimal mitigation for EOL version" patches for 7.4, 8.0 and 8.1, and vendors have packaged them (ComputingForGeeks, AlmaLinux).

Platform How to update
Ubuntu / Debian (incl. Ondřej Surý packages) sudo apt update && sudo apt install --only-upgrade 'php8.1*' (match your version)
RHEL, Rocky, AlmaLinux sudo dnf upgrade --refresh 'php*'; if your stream is retired, switch to the matching Remi stream
Remi software collections sudo dnf upgrade -y 'php81-*'
cPanel / DirectAdmin Update EasyApache 4 (ea-php81, ea-php80, ea-php74) or CustomBuild PHP

Then restart every pool: sudo systemctl restart php8.1-fpm (and Apache if you use mod_php).

Verify by changelog, not version number. Patched builds keep the same version string (for example 8.1.34). Look for the CVE in the package changelog:

zgrep CVE-2026-109618 /usr/share/doc/php8.1-fpm/changelog.Debian.gz   # Debian/Ubuntu
rpm -q --changelog php81-php-fpm | head -5                            # Remi / RPM

3. Turn off session upload progress

Set it for every PHP version, in php.ini and in each FPM pool:

; php.ini
session.upload_progress.enabled = Off
; /etc/php/8.1/fpm/pool.d/www.conf (each pool)
php_admin_flag[session.upload_progress.enabled] = off

Restart PHP-FPM (or Apache with mod_php). The PHP Foundation recommends keeping it off until the next PHP release. To confirm what the web server sees, check phpinfo() from a temporary page, then delete that page.

4. Do not remove the memory limit

Some early advice suggested memory_limit = -1 to avoid the out-of-memory trigger. Don't: one request can then consume all server memory. Keep a sensible limit.

5. If there is no patched package (PHP 7.3 and older)

  • Put the site behind a WAF with PHP2Shell rules enabled, in blocking mode.
  • Block multipart/form-data on every route that does not need uploads (example below).
  • Restrict admin panels to a VPN or allow-listed IPs.
  • If the server cannot be protected, take it offline until it is upgraded.

6. Plan the upgrade

Backports are a one-off rescue. The next PHP flaw may not get one. Schedule the move to PHP 8.2 or later now.

Samples: what breaks, and how to work around it

Upload progress bars stop updating

This classic pattern reads progress from the PHP session, so it stops working once session.upload_progress.enabled is off (and on patched EOL builds, which disable the feature in code):

<?php // progress.php: polled by the browser during an upload
session_start();
$key = ini_get('session.upload_progress.prefix') . 'avatar';
echo json_encode($_SESSION[$key] ?? null); // now always null

Workaround: measure progress in the browser instead. It needs no PHP session and works on every PHP version:

<input type="file" id="file"> <progress id="bar" max="100" value="0"></progress>
<script>
  document.getElementById("file").addEventListener("change", (e) => {
    const data = new FormData();
    data.append("avatar", e.target.files[0]);
    const xhr = new XMLHttpRequest();
    xhr.upload.onprogress = (p) => {
      if (p.lengthComputable) document.getElementById("bar").value = (p.loaded / p.total) * 100;
    };
    xhr.open("POST", "/upload.php");
    xhr.send(data);
  });
</script>

Out-of-memory requests fail harder on patched EOL builds

With the backport, a request that exceeds memory_limit ends the PHP worker immediately: shutdown functions don't run and visitors see a 502 or 503 instead of a PHP error. If a heavy page (large import, report, image resize) starts failing:

; FPM pool: make the error visible in logs
catch_workers_output = yes

Watch the FPM log for exited with code 1 and raise memory_limit for that pool if needed.

Blocking multipart breaks uploads on blocked routes

An nginx example that blocks multipart requests everywhere except the endpoints that genuinely accept files:

# inside the server { } block
set $block_multipart 0;
if ($content_type ~* "^multipart/form-data") { set $block_multipart 1; }
if ($request_uri ~* "^/(wp-admin/async-upload\.php|account/avatar)") { set $block_multipart 0; }
if ($block_multipart) { return 403; }

Test your contact forms, checkouts and admin uploads after enabling it, and keep the allow-list short.

About CVE-2026-115560

As of 23 October 2026, PHP describes CVE-2026-115560 as an unlikely remote code execution path that needs an unusual setup: the server uses a non-default session.serialize_handler and the application switches it to php at runtime before starting the session, with upload progress enabled. No public exploit is known. The fix is planned for the next regular release, so keep session.upload_progress.enabled = Off and update again when it ships.

How Intelvue can help

Our team has patched and hardened PHP platforms for more than a decade, including WordPress, Magento and custom PHP on old versions. We can:

  • Find every PHP install on your servers and confirm each one is patched.
  • Apply the right backport or workaround for your stack without breaking checkout, uploads or admin.
  • Replace session-based upload progress bars and test the site end to end.
  • Plan and run the upgrade to supported PHP.

See our security audits and compliance service, or talk to an engineer today.

Frequently asked questions

Can I fix PHP2Shell without upgrading to PHP 8.2 or later?
Yes, for PHP 7.4, 8.0 and 8.1. PHP published minimal source patches for those branches and most distributions and control panels (Ubuntu, Remi, cPanel, DirectAdmin, Red Hat, AlmaLinux) ship them as package updates. PHP 7.3 and older have no official fix.
Does session.upload_progress.enabled = Off fix PHP2Shell?
No, not on its own. It blocks the new CVE-2026-115560 path and is recommended against CVE-2026-109619, but PHP developers say it is not enough by itself and it does nothing for CVE-2026-109618. Use it together with a patched PHP build.
What breaks when I disable session upload progress?
Only upload progress bars that read progress from the PHP session. File uploads themselves keep working. You can replace the progress bar with a browser-side one that needs no PHP session.
Should I set memory_limit to -1 to avoid the out-of-memory trigger?
No. With memory_limit = -1, a single request can use all server memory and take the whole server down. Keep a sensible limit and install the patched build.
Is CVE-2026-115560 fixed in the 21 October releases?
No. As of 23 October 2026, PHP says the fix will come in the next regular release. Until then, set session.upload_progress.enabled to Off and keep it off.

Watch: the video explainer

PHP2Shell Explained: One Request Takes Over Your Server · The Tech Breakdown · Watch on YouTube (opens in a new tab)