Security · PHP

PHP2Shell: which PHP versions are affected, and how to actually get the fix

On 21 October 2026 the PHP project shipped emergency releases for two critical, unauthenticated remote code execution bugs. Running apt upgrademay not have installed them. This guide covers what's affected, how to confirm the build you're really running, and what to do on Ubuntu, Laravel Forge, cPanel, Plesk and managed hosting.

PHP2Shell: affected PHP versions and how to update
By Ritesh Agarwal9 min read

TL;DR

Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or to your distribution's patched package, then restart every PHP worker. The two bugs (CVE-2026-109618 and CVE-2026-109619, nicknamed PHP2Shell) are each rated CVSS v4.0 9.2 and can give an unauthenticated attacker code execution as the web server user, before your application runs.

Don't trust the upgrade command. Check the installed version. On release day the Ondřej PPA used by Laravel Forge still served 8.3.35, which is notfixed. Until you're patched, set session.upload_progress.enabled=0 and lower post_max_size. These reduce risk but don't remove it.

What happened

The PHP security team gave advance notice on 20 October and published the releases on 21 October 2026, a little ahead of the announced 14:00 UTC slot. The php.net announcement says every PHP installation that serves web requests is at risk, including PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed. It rates the risk highest for mod_php, where a demonstrated exploit works before any application code runs. php.net security advisory

The CVE IDs leaked ahead of the planned disclosure, and the security press quickly settled on the name PHP2Shell, which is also the name of a public exploit tool that chains the two bugs. Researchers have demonstrated unauthenticated RCE against stock WordPress, Drupal, Joomla and Magento installs, because the flaw sits under all of them.

Which PHP versions are affected, and which are fixed?

BranchVulnerableFixed upstreamNotes
PHP 8.5below 8.5.128.5.12Extra RCE path via fatal_error_backtraces
PHP 8.4below 8.4.278.4.27
PHP 8.3below 8.3.368.3.368.3.35 is not fixed
PHP 8.2below 8.2.358.2.35End of life 31 December 2026
PHP 8.1, 8.0, 7.4Assume yesNo releaseSource backports only; see below

Distribution packages carry their own version strings. Ubuntu's security notice USN-8948-1 fixes 24.04's PHP as 8.3.6-0ubuntu0.24.04.13 and 22.04's PHP 8.1 as 8.1.2-1ubuntu2.28. Those are patched even though the upstream number looks old. For distro PHP, compare the package version with your vendor's advisory, not with “8.3.36”. Ubuntu USN-8948-1

The two bugs in plain English

CVE-2026-109618: RCE via out-of-memory corruption

When PHP runs out of memory it jumps straight out of the request. If that happens while a request is only partly set up, for example while parsing a crafted multipart upload, the clean-up code then treats half-initialised memory as valid. An attacker can steer that into code execution. Requests without a usable content length, parts with unlimited headers and piles of empty file fields can all trigger it. GHSA-w8hw-w9fx-j79w

CVE-2026-109619: RCE via stale global state

PHP workers are reused across requests. After a fatal error, some state a worker keeps between requests can still point at memory the previous request freed. The next request on that worker can touch it before normal initialisation resets it, which is a classic use-after-free. The confirmed paths include session upload progress, which is on by default and needs no session_start(), and on PHP 8.5 the fatal error backtrace feature. GHSA-6wmf-4rv5-p3rp

Who is at risk: mod_php, PHP-FPM, LSAPI or FrankenPHP?

SAPICVE-2026-109618 (OOM)CVE-2026-109619 (stale state)
Apache mod_phpConfirmed RCEConfirmed RCE
PHP-FPMLikely (source analysis, no full exploit shown)Confirmed via session upload progress
FrankenPHPLikelyNo default early path found; not immune
LiteSpeed LSAPILikelyConditional

Most Laravel, Symfony and modern WordPress hosting runs PHP-FPM behind nginx, so “we don't use mod_php” isn't a reason to wait.

How to check your PHP version properly

php -v only shows the command-line binary. Your sites are served by PHP-FPM or the Apache module, which can be a different package or even a different version. Check what serves traffic, and check the package version:

Check the CLI, the FPM binary and the installed packagesbash
# The CLI and the web SAPI can be different builds: check both
php -v
php-fpm8.3 -v            # adjust to your version: php-fpm8.2, php-fpm8.4 ...

# The package version is what matters (distros backport fixes)
dpkg -l 'php*' | awk '/^ii/{print $2, $3}'          # Debian / Ubuntu
rpm -qa 'php*' | sort                                # RHEL / Alma / Rocky

On WordPress, Tools → Site Health → Info → Servershows the PHP version the site actually runs on. If you're on cPanel, check every ea-php version in use, not just the default. Not technical? Our plain-English guide for WordPress site owners explains what to ask your host.

How to update PHP

Ubuntu and Debian with Ondřej Surý's PPA

Upgrade, restart and confirm nothing runs the old binarybash
sudo apt-get update
apt-cache policy php8.3-fpm          # is the candidate 8.3.36 (or your distro's fixed build)?
sudo apt-get install --only-upgrade 'php8.3*'
sudo systemctl restart php8.3-fpm    # restart, not reload: every worker must be replaced

# Anything still running the old, deleted PHP binary?
sudo grep -lE ' /(usr|lib|opt).*\(deleted\)$' /proc/[0-9]*/maps

The catch on release day: the Launchpad PPA (ppa:ondrej/php) still listed 8.5.11, 8.4.26 and 8.3.35 hours after the release, while Ondřej's separate packages.sury.org repository had fixed amd64 builds sooner. Ondřej Surý has confirmed the fix is coming to every PHP version he ships. If apt-cache policydoesn't show the fixed version yet, you're not patched. Apply the mitigations below and check again. ma.ttias.be patch-status tracker

Laravel Forge

Forge provisions PHP from the same Ondřej PPA, so neither Forge's PHP management nor an SSH session can install 8.3.36 before the PPA publishes it. That's exactly what we hit on a client server today. We installed the newest build the PPA offered, confirmed it was still 8.3.35, and added session.upload_progress.enabled=0 as a conf.ddrop-in. We then restarted PHP-FPM and checked every site on the box. The job isn't finished until php-fpm8.3 -vreads 8.3.36. If you're weighing Forge against managed platforms that patch the runtime for you, our Laravel Cloud vs Forge comparison covers that trade-off.

cPanel / WHM and Plesk

cPanel ships PHP as EasyApache 4 ea-php packages, and CloudLinux as alt-php, so the fix arrives when those vendors publish rebuilt packages. Run the system update (or WHM → EasyApache 4) and confirm each /opt/cpanel/ea-phpXX/root/usr/bin/php -v. Plesk has said every PHP version it ships is affected and is rebuilding them. Check Tools & Settings → Updates and plesk bin php_handler --list.

Managed and shared hosting

You can't patch PHP yourself here. Ask your host for the exact package version and the time it was deployed, in writing. A .user.ini or ini_set()change doesn't apply the mitigations, because they have to take effect before the request is parsed.

What to do if you can't update yet

php.net is explicit that these measures “do not make an installation safe”. They block the confirmed paths only. Apply them in php.ini, a conf.d file or the FPM pool, then restart every worker:

Interim hardening while the fixed package is unavailableini
; /etc/php/8.3/fpm/conf.d/99-php2shell.ini  (and apache2/conf.d for mod_php)
; Interim only: reduces exposure, does not fix CVE-2026-109618/109619
session.upload_progress.enabled = 0
post_max_size = 8M          ; 32M if the app needs uploads
upload_max_filesize = 6M    ; keep below post_max_size
; PHP 8.5 only:
; fatal_error_backtraces = 0
  • Cap request body size, field count, multipart parts and header count at nginx, Apache or your proxy, including requests with no Content-Length.
  • Block multipart/form-data entirely on apps that never take uploads.
  • For CVE-2026-109618, php.net's primary config workaround is memory_limit=-1 enforced with php_admin_value. It's still incomplete, and you need a container or cgroup memory limit to stay available. Never use RLIMIT_AS/RLIMIT_DATA, which trigger the bug.
  • Remove deprecated or invalid per-request INI settings that emit diagnostics, and consider pm.max_requests=1 if you can afford the performance cost.
  • Watch for multipart requests followed by memory-limit errors, bursts of HTTP 500s, oversized PHPSESSID cookies and unexplained worker restarts.

If a high-risk site can't be patched or mitigated quickly, take it offline at the web server or proxy until it can.

Still on PHP 7.4, 8.0 or 8.1?

The PHP project no longer releases these branches. PHP 7.4 has been end of life since November 2022. Given the severity, the security team did publish minimal source backports for 7.4, 8.0 and 8.1, but they only help you if you build PHP from source. For everyone else:

  • Distro PHP (Ubuntu 22.04's PHP 8.1, Debian, RHEL): your vendor may ship a backport. Ubuntu already has, in 8.1.2-1ubuntu2.28.
  • PPA or vendor builds: check whether the provider rebuilds old branches. Otherwise ask an extended-support (LTS) vendor.
  • Plan the upgrade. Researchers say the vulnerable code dates back to PHP 5.4, so “old” doesn't mean “unaffected”. Move to 8.3 or 8.4, not 8.2, which itself ends on 31 December 2026.

Frequently asked questions

Is PHP2Shell being exploited in the wild?
Treat it as exploited. Cloudflare reported early attack activity against PHP sites on the morning of 21 October 2026, before the fixed releases were out, and Patchstack said hosting partners reported incidents the same morning. Proof-of-concept code is public, though some of what circulates is unverified and may itself be malicious.
Does updating WordPress, Laravel or my plugins fix PHP2Shell?
No. Both bugs are in the PHP interpreter and are reachable before your application code runs, so a clean, fully updated WordPress, Magento or Laravel site is still exposed on a vulnerable PHP build. WordPress maintenance mode doesn't help either. Only the PHP package on the server, or your host's update, fixes it.
Does a WAF or Cloudflare protect me from PHP2Shell?
Partly. Cloudflare deployed WAF rules for known exploit vectors, but they only cover traffic that actually passes through Cloudflare, and new variants can get past a signature. A WAF buys time. It doesn't replace the update.
Does 'apt upgrade' fix PHP2Shell?
Only if your package source has published the fixed build. On 21 October the ppa:ondrej/php archive used by Laravel Forge still served 8.3.35, which does not contain the fix, so apt upgrade reported success without patching anything. Always confirm the installed package version afterwards and restart PHP-FPM or Apache.
Should I keep session.upload_progress disabled after patching?
Yes, if your application doesn't show upload progress bars from PHP's session upload progress feature. The advisory for CVE-2026-109619 suggests leaving it off even after patching when you don't need it, and most modern apps don't.

Primary sources

Our clients

UK · Europe · Worldwide

Selected case studies

What we built, how it works and the results for our clients.

Creoate product interface01
B2B commerce

Eight years behind a wholesale marketplace

Next.js storefront, Python ingestion pipelines, DynamoDB data layer and AWS infrastructure.

8+ yearsdevelopment and support
Ontick product interface02
Event technology

Ticketing owned by the event team

Multi-organiser commerce, Stripe instalments and two native apps in one connected platform.

£2M+ticket sales processed
Easyship product interface03
Global logistics

Helping shippers compare their options

Rate, tax and duty calculators, server-rendered courier pages and a custom MongoDB CMS.

550+couriers in the calculator
TEFL.ie product interface04
Education & training

Connecting course sales to the classroom

WordPress and WooCommerce, a Moodle LMS, Stripe deposits and Zoho CRM, tied together with Zapier automation.

Since 2017development and support
All White Laser product interface05
Medical aesthetics

From equipment finance to clinic support

A lead-to-billing system on GoCardless Direct Debit, provider certification, and a React Native app for machine owners.

9 yrsdevelopment and support
Decofetch product interface06
Luxury commerce

A custom home for designer furniture

Server-rendered Next.js commerce over a Laravel API, bespoke operations tooling and re-architected AWS infrastructure.

0→livemarketplace development
BA Engine Room product interface07
AI operations

Connecting discovery, contracts and delivery

Discovery briefs, e-signed contracts, Stripe deposits, delivery milestones and time tracking in one operational system.

0→1custom platform development
PlusHeat product interface08
Home services

Helping customers choose their boiler cover

Custom plan configuration, postcode-qualified lead journeys, CRM synchronisation and campaign landing pages.

5 yrswebsite development and support
Léonia product interface09
Beauty commerce

Shopify shaped around a beauty brand

Custom theme, customer accounts, loyalty rewards, referrals and gift-with-purchase offers.

5 yrsShopify development and support
Shutters 365 product interface10
Home improvement

From window measurements to a priced order

A seven-step product builder with live previews, sample orders and supplier tools.

7-stepproduct configurator
Bloc Ads Manager product interface11
Advertising

From targeted ads to venue check-ins

Campaign creation, audience targeting, in-app ads and reporting linked to venue check-ins.

check-inscampaign attribution
Bloc product interface12
Social events

Four years across the app and operations

Mobile app, backend, advertising tools, a digital marketplace and website.

4+ yrssupport across five codebases
Zonely product interface13
Social mobile

Two apps, one real-time conversation marketplace

Customer and buddy apps with per-minute billing, wallets, moderation and admin tools.

2 appsfor iOS and Android
Player Profile Hub product interface14
Grassroots football

Helping grassroots players get discovered

Verified profiles, video highlights, coach discovery and safeguarding on web and mobile.

0→1custom platform development
DeepSpatial product interface15
Geospatial AI

Connecting clients, investors and emerging talent

Corporate and investor pages, the Xploor talent platform and ongoing releases on AWS Amplify.

2 yrsdevelopment and support
Yippee Malta product interface16
Travel

A booking journey the tour team owns

A multilingual website connected to the booking API, with deposits, coupons and affiliate tracking.

6languages across the booking journey
Professional Energy product interface17
Energy brokerage

Tenders, contracts and accounts brought together

Supplier tenders, contract management, brokerage accounting and client records.

100+suppliers per tender

Need PHP2Shell patched and verified today?

Same-day PHP patching, mitigation and compromise checks, by engineers who run Forge, cPanel and Plesk estates daily.