Skip to content
SecurityReviewby ServiceVision

PHP2Shell: what happened and what to do

A plain-English advisory for website owners and the people who look after their sites.

Last reviewed 23 October 2026

Summary

On 21 October 2026 at 14:00 UTC the PHP project released emergency updates for two critical flaws in the PHP interpreter, nicknamed PHP2Shell. Both are rated 9.2 on CVSS v4.0 and both allow remote code execution without logging in, on any server that serves web pages with PHP.

Researchers also showed the flaws can reveal the memory of PHP worker processes. That memory can hold passwords, session tokens, API keys and certificates.

The flaws are in PHP itself, not in any application or Composer package. Updating your application or its dependencies does nothing. The PHP software on the server must be updated and every PHP worker restarted.

The two flaws

The two PHP2Shell vulnerabilities
CVEWhat goes wrong
CVE-2026-109618If memory runs out while PHP is still setting up its internal request data, the cleanup that follows can treat half-built data as valid. This is memory corruption after an out-of-memory error.
CVE-2026-109619Leftover state from one request points at memory that has been freed, and a later request handled by the same worker can then use it. This is a use-after-free across requests.

Wiz describes four underlying bugs and groups them slightly differently between the two CVE numbers. The descriptions agree on the mechanism: state that survives a failed or finished request is reused by the next one.

Who is affected

  • Versions: every PHP release since 5.4.0.
  • Deployment types: every installation that serves web requests, including PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed. The command-line PHP binary is not listed as affected.
  • Highest risk: Apache with mod_php, where a demonstrated exploit fires on a request without login, before any application code runs. No application-level control can stop it.
  • Applications: code execution was demonstrated against the latest WordPress, Drupal and Joomla.

Timeline

PHP2Shell timeline, 2026
Date (2026)What happened
19 AugResearchers at Calif, OpenAI and Wiz discover the flaws using AI-assisted analysis
20 to 21 AugCode execution confirmed against Drupal and WordPress
24 AugReported to the PHP security team
21 SepPHP begins developing fixes
17 OctAmazon Threat Intelligence sees a first exploitation attempt against its honeypots, four days before disclosure
20 OctCVE numbers circulate publicly and PHP issues advance notice
21 Oct, 14:00 UTCPHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 released. CISA publishes an alert. Ubuntu publishes USN-8948-1 and USN-8948-2
22 OctAmazon reports the flaws are being broadly exploited in the wild

Any PHP server reachable from the internet was exposed from at least 17 October until it was patched and restarted.

Fixed versions

PHP released fixed versions for every supported branch on 21 October 2026. Your server should be on one of these, or later:

PHP2Shell fixed versions by PHP branch
PHP branchFixed in
PHP 8.58.5.12
PHP 8.48.4.27
PHP 8.38.3.36
PHP 8.28.2.35
PHP 7.4 to 8.1No official release. These versions are past end of life. The PHP security team published minimal source patches only. Upgrade if you can.
PHP 5.4 to 7.3No fix. Past end of life with no fix at all. Upgrade, or put the site behind a web application firewall or take it offline.

Some providers, including Ubuntu and Hostinger, apply the fix without changing the version number. A site can be patched and still report an older version, so the version alone is not proof either way.

Ubuntu

Ubuntu applies the fix without changing the PHP version number. A patched Ubuntu 24.04 server still reports PHP 8.3.6. Check the package version (dpkg -l | grep php8) instead.

Ubuntu packages that fix PHP2Shell (USN-8948-1, USN-8948-2)
ReleasePackageFixed in (or later)
26.10php8.58.5.9-0ubuntu2.1
26.04 LTSphp8.58.5.4-0ubuntu1.5
24.04 LTSphp8.38.3.6-0ubuntu0.24.04.13
22.04 LTSphp8.18.1.2-1ubuntu2.28
20.04php7.47.4.3-4ubuntu2.29+esm5 (Ubuntu Pro)
18.04php7.27.2.24-0ubuntu0.18.04.17+esm14 (Ubuntu Pro)
16.04php7.07.0.33-0ubuntu0.16.04.16+esm22 (Ubuntu Pro)
14.04php55.5.9+dfsg-1ubuntu4.29+esm18 (Ubuntu Pro)

Non-LTS releases past end of life, such as 24.10 and 25.04, get no fix.

Other platforms

Ondřej Surý PPA (ppa:ondrej/php)
Tracks upstream PHP. Patched packages report the upstream fixed versions: 8.2.35, 8.3.36, 8.4.27 and 8.5.12.
Containers
Rebuild images on the fixed tags (php:8.x-fpm, php:8.x-apache, wordpress:php8.x) pulled after 21 October, then redeploy. A running container keeps its old PHP until it is rebuilt.
After any update
Restart every PHP worker: Apache, PHP-FPM and LiteSpeed lsphp. Patched files on disk do nothing until the running workers are replaced.

Managed hosting status

What the larger hosts have said publicly. Check your host's own notice for the latest.

Managed host PHP2Shell status
HostStatusWhat they saidDate
HostingerPatched, verify the build datePHP upgrades complete on all managed servers; version number may not change Source for Hostinger23 October 2026
WP EnginePatchedfinished the deployment of security patches Source for WP Engine22 October 2026
NexcessStill patchingcontinue to assess the remaining hosting environments Source for Nexcess23 October 2026
SiteGroundPatchedStates sites are protected Source for SiteGround23 October 2026
GoDaddyRolling updatesRolling updates; check the PHP Info build date or the provider notice Source for GoDaddy23 October 2026
cPanel or Plesk hostRolling updatesRolling updates across cPanel and Plesk hosts; check the PHP Info build date or the provider notice Source for cPanel or Plesk host23 October 2026

On Hostinger, open hPanel, then Websites, then Dashboard, then PHP Info. The Build Date must be 21 October 2026 or later. The version shown in the x-powered-by header may still be the old patch number.

Finding exposed PHP

From outside
The x-powered-by: PHP/x.y.z response header, where a server shows it. It is unreliable for patch status on hosts that patch without changing the version, and missing where expose_php is off.
On the server
php -v, dpkg -l | grep php, the PHP Info Build Date, and the package source (apt-cache policy).
Scanners
Nessus plugin 369483 has local and remote checks. The remote check only works when the server shows its PHP version.

Stopgap settings

These settings block specific attack paths and buy time until you can update. PHP is explicit that they do not make an installation safe.

Interim PHP configuration mitigations for PHP2Shell
SettingTargetsNotes
memory_limit=-1 (set so the application cannot override it)CVE-2026-109618Removes the out-of-memory trigger but allows unbounded memory use, so pair it with a container or cgroup memory limit.
session.upload_progress.enabled=0CVE-2026-109619Turns off the upload progress feature used by the published exploit.
fatal_error_backtraces=0 (PHP 8.5 only)CVE-2026-109619Removes the backtrace use-after-free path.

Restart every PHP worker after changing any of these. Cloudflare and other firewall vendors have deployed rules; treat them as a stopgap only. Where patching is not possible at all, CISA's guidance is to put the system behind a web application firewall or take it offline.

Signs of compromise

From the Wiz and Tenable write-ups:

  • Unusual file-upload requests followed by memory-limit errors in the PHP log
  • Repeated HTTP 500 responses from otherwise healthy pages
  • Malformed PHPSESSID cookies in responses
  • PHP workers restarting or crashing more often than usual
  • PHP worker processes launching shells or downloading tools (sh, bash, curl, wget or nc running as the web user)

Checks to run on the server:

  • PHP files created or changed since 17 October 2026 that you did not deploy
  • Any .php file in upload or storage folders
  • Unknown administrator accounts (on WordPress) and unknown scheduled tasks for the web user
  • POST requests answered with 4xx or 5xx errors in the access log around the exposure window

Rotating secrets

Because the flaws leak worker memory, a server that was reachable while unpatched may have exposed any secret its PHP processes held. Rotate database passwords, third-party API keys, OAuth and JWT signing keys, and service account keys.

Treat application encryption keys separately. WordPress salts are cheap to rotate: everyone is logged out and nothing else breaks. Laravel's APP_KEY should stay unless there is evidence of compromise, because changing it makes data encrypted with the old key unreadable.

Talk it through with a ServiceVision engineer. We'll go over what we found, what it means for your site and what to do next.

Book a call about your results (opens in a new tab)

Sources