Still on PHP 8.1, 8.0 or 7.4? What to Do About PHP2Shell When There Is No Official Update
PHP's October 2026 fix only covers 8.2 and newer. Here are your real options on PHP 8.1, 8.0 and 7.4: distro backports, building the official backport branch, safe upgrade steps and code fixes for common breaking changes.
PHP2Shell (CVE-2026-109618 and CVE-2026-109619) affects PHP 5, 7 and every 8.x branch. The official fixed releases, 8.5.12, 8.4.27, 8.3.36 and 8.2.35, only cover supported branches. If your site runs PHP 8.1, 8.0, 7.4 or older, there is no official upgrade button to press. This guide explains your real options, from quick protection to a proper upgrade, with code examples for the most common breaking changes.
The Hard Truth About Old PHP
- PHP 8.1 reached end of life on December 31, 2025.
- PHP 8.0 and all of PHP 7.x were already end of life before that.
- The PHP project does not publish releases for these branches anymore, including for PHP2Shell.
- PHP 8.2 is patched (8.2.35) but reaches end of life on December 31, 2026, so moving to 8.2 today buys only about ten weeks.
Because this flaw is critical, the PHP security team made an exception and published minimal source-level backports for 7.4, 8.0 and 8.1. These are meant for people who compile PHP themselves or have no access to a long-term support vendor. They are not full releases and do not include any other security fixes those branches have missed since going end of life.
Option 1: Get a Backported Package (Fastest)
Many sites on old PHP are on a Linux distribution or control panel that still maintains that version. Check these first:
- Ubuntu and Debian: distributions such as Ubuntu 22.04 ship PHP 8.1 and provide their own security fixes for it. Run
sudo apt updateand upgrade, then confirm with the changelog check below. - Ondřej Surý packages (sury.org): backported the fix to PHP 8.1 and older.
- cPanel: released updated packages that include fixes for PHP 8.1, 8.0 and 7.4.
- Plesk: released fixes for 8.2 to 8.5, with 8.0 and 8.1 patches announced as in development.
- Commercial long-term support vendors: if you pay for extended PHP support, ask them for the PHP2Shell backport.
zgrep -E 'CVE-2026-10961(8|9)' /usr/share/doc/php8.1-common/changelog.Debian.gz
rpm -q --changelog php-common | grep -E 'CVE-2026-10961(8|9)'Option 2: Build From the Official Backport Branch
If you compile PHP yourself, you can build from the security branch the PHP team published:
# Build PHP 8.1 from the official minimal security backport branch
# (branches also exist for 7.4 and 8.0)
php -i | grep 'Configure Command' # save your current options first
git clone --depth 1 --branch PHP-8.1-CVE-2026-109618-109619 https://github.com/php/php-src.git
cd php-src
./buildconf --force
./configure <your previous configure options>
make -j$(nproc)
sudo make install
sudo systemctl restart php-fpmTest on a staging server first and keep your previous binary so you can roll back.
Option 3: Upgrade to a Supported PHP Version (The Real Fix)
Backports close this hole, but an end-of-life PHP will keep collecting unpatched vulnerabilities. The lasting solution is to upgrade. Because 8.2 expires at the end of 2026, aim for PHP 8.4, which is supported until December 31, 2028, or at least 8.3, which is supported until December 31, 2027.
A Safe Upgrade Workflow
- Clone the site to a staging environment that runs the target PHP version.
- Update your CMS, framework, plugins and themes first. Old plugins are the most common cause of breakage.
- Run the automated compatibility checks below.
- Turn on full error reporting on staging and click through every important page, form, login and checkout.
- Switch production during a quiet period, with a backup ready and a rollback plan.
Automated Compatibility Checks
# 1. Will your Composer dependencies install on the target version?
composer why-not php 8.4.0
# 2. Scan your own code for incompatibilities (PHP_CodeSniffer + PHPCompatibility)
composer require --dev phpcompatibility/php-compatibility
vendor/bin/phpcs -p src/ --standard=PHPCompatibility --runtime-set testVersion 8.4 --extensions=php
# 3. Let Rector fix many issues automatically (preview first)
composer require --dev rector/rector
vendor/bin/rector process src --dry-run<?php
// rector.php
use Rector\Config\RectorConfig;
return RectorConfig::configure()
->withPaths([__DIR__ . '/src'])
->withPhpSets(php84: true);Common Breaking Changes, With Fixes
Dynamic properties (deprecated in 8.2)
<?php
// PHP 8.2+ deprecates creating properties that were never declared
class User {
public string $name;
}
$u = new User();
$u->age = 30; // Deprecated in 8.2
// Fix: declare the property
class User {
public string $name;
public ?int $age = null;
}
// Or, for legacy classes you cannot refactor yet:
#[\AllowDynamicProperties]
class LegacyUser {}Implicitly nullable parameters (deprecated in 8.4)
<?php
// PHP 8.4 deprecates implicitly nullable parameters
function findUser(int $id, Logger $logger = null) {} // Deprecated in 8.4
// Fix: make the nullability explicit
function findUser(int $id, ?Logger $logger = null) {}Passing null to internal functions (deprecated in 8.1)
<?php
// PHP 8.1+ deprecates passing null to non-nullable internal parameters
$title = $_POST['title'] ?? null;
echo strlen($title); // Deprecated when $title is null
echo htmlspecialchars($title); // Same problem
// Fix: provide a string default
$title = $_POST['title'] ?? '';
echo strlen($title);String interpolation, utf8_encode and comparisons
<?php
// PHP 8.2 deprecates ${var} string interpolation
echo "Hello ${name}"; // Deprecated
echo "Hello {$name}"; // Correct
// PHP 8.2 deprecates utf8_encode() / utf8_decode()
$out = utf8_encode($in); // Deprecated
$out = mb_convert_encoding($in, 'UTF-8', 'ISO-8859-1'); // Replacement
// PHP 8.0 changed string-to-number comparison (important for 7.4 users)
var_dump(0 == 'abc'); // PHP 7.4: true PHP 8.x: falseDeprecations do not break your site immediately, but they fill your logs and turn into fatal errors in future major versions, so fix them while you are already testing.
Option 4: Protect the Site While You Work
If neither a backport nor an upgrade can happen today, reduce exposure in the meantime:
- Apply the interim settings from our mitigation guide, especially
session.upload_progress.enabled=0, and restart every worker. - Put the site behind a web application firewall such as Cloudflare, which released rules for these attacks, and lock the origin so it only accepts CDN traffic.
- Move away from Apache mod_php to PHP-FPM if you can, since mod_php is the highest-risk setup.
- If you run your own server and none of the above is possible, consider taking the site offline or behind a login until it is patched. WordPress.org and the UK National Cyber Security Centre both raised this as an option.
Quick Checklist for Sites Below PHP 8.2
- Find your exact PHP version and source using our check guide.
- Look for a vendor or distro backport and install it today if available.
- Otherwise apply mitigations and a WAF immediately.
- Start a staging upgrade to PHP 8.4 this week.
- Do not settle on 8.2, because it reaches end of life on December 31, 2026.
Official Links
Admin PenduCoder
Full-stack developer and educator. Writes about Laravel, Next.js, applied AI and the unglamorous parts of shipping software.
Get in touch →