PHP2Shell: Check Your Website Servers and Patch Today

Posted by:

|

On:

PHP2Shell – TL;DR

On October 21, 2026, the PHP project shipped emergency fixes for two critical flaws in PHP itself, nicknamed PHP2Shell. An attacker with no password can use crafted web requests to run code on an unpatched server, and attack attempts started before the fix was public. If anything you run touches PHP, including a WordPress marketing site, this is a today problem.

  • Update PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or install your Linux distro’s or host’s fixed package.
  • Restart every PHP worker afterwards; a running process keeps the old code in memory.
  • Don’t trust php -v. Vendor fixes often keep the old version number.
  • Rebuild your containers. Patching the host doesn’t touch the PHP inside them.
  • On PHP 8.1 or older with no vendor backport, upgrade or take the site offline.

This guide covers what happened, how to check your servers in about 30 minutes, how to fix them, and how to tell whether anyone got in before you patched. Feel free to share it or link to it from your own runbooks; the vendor status sections are updated as fixes roll out.

In this guide

What is PHP2Shell?

PHP2Shell is two memory-safety bugs in PHP’s core, tracked as CVE-2026-109618 and CVE-2026-109619 and rated 9.2 out of 10 (CVSS v4.0). They live in the interpreter, below WordPress, Laravel, Drupal or your own code, so a fully updated app is still exposed if the PHP underneath it isn’t patched.

CVEPHP’s name for itWhat goes wrong, in plain English
CVE-2026-109618RCE via OOM corruptionIf PHP runs out of memory partway through reading a request, such as a large form or upload, its cleanup step can treat half-built internal data as valid.
CVE-2026-109619RCE via stale global stateData from one request can outlive the memory behind it, and the next request on the same worker can use it before it’s reset.

Every PHP setup that serves web requests is at risk: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. PHP rates mod_php highest, because a demonstrated exploit fires before any application code runs (PHP advisory).

Three details make this worse than a typical CVE:

  • It isn’t theoretical. Wiz Research, which co-discovered the bugs, ran code without logging in on stock WordPress, Drupal and Joomla installs, and showed attackers can read worker memory holding passwords and API keys (SOCRadar’s summary).
  • Attacks started early. Amazon’s honeypots logged an attempt on October 17, four days before the fix, and watchTowr and Cloudflare reported attacks on release day (Greenbone, Tanium).
  • AI shortened the clock. Wiz says frontier AI models helped find the bugs and chain them into working exploits. Expect the gap between a disclosure and real attacks to keep shrinking.

One caution: fake “PHP2Shell exploit” and “scanner” repositories often carry malware. Don’t run them on your servers.

PHP2Shell Timeline: patch and attacks, Oct 21–23

DateTime (PT)What happenedSource
Oct 22–23Not publishedPHP flags a third, unlikely variant (CVE-2026-115560) and advises keeping session upload progress off until its next regular releasePHP
Oct 2210:40 AMwatchTowr updates its FAQ: exploitation observed in the wild, and neither CVE is in CISA’s Known Exploited Vulnerabilities catalog yetwatchTowr
Oct 213:36 PMAmazon discloses an exploitation attempt dated Oct 17 and says PHP2Shell is now being broadly exploitedAWS
Oct 217:19 AMwatchTowr reports active exploitation attempts against both CVEsRescana
Oct 216:30 AMPHP ships 8.5.12, 8.4.27, 8.3.36 and 8.2.35, ahead of its 7:00 AM schedule; its GitHub advisories follow at 6:34 AMCERT-EU, Rescana
Oct 214:35 AMHadrian reports exploitation “at scale”Rescana
Oct 2112:34 AMPatchstack logs exploitation incidents reported by hosting partnersRescana

PHP2Shell Timeline: leak and first exploits, Oct 17–20

DateTime (PT)What happenedSource
Oct 20Before 10:00 PMCERT-EU publishes advisory 2026-018, advising isolation of internet-facing PHP appsVincent Schmalbach
Oct 208:02 PMCloudflare’s WAF protections switch on by default for every planRescana
Oct 207:00 PMAmazon sees its first proof-of-concept exploits, then more attempts against its honeypots until 1:00 AMAWS
Oct 2012:35 PMwatchTowr publicly confirms the leaked flaws are realwatchTowr
Oct 2012:33 PMPHP announces an emergency release for 7:00 AM the next dayVincent Schmalbach
Oct 209:39 AMSecurity researcher Kevin Beaumont flags the leak publiclyVincent Schmalbach
Oct 208:00 AMThe CVE IDs start circulating online with an inflated CVSS 10.0 score and no technical detailsRescana
Oct 17Not publishedAmazon’s honeypots log the first known exploitation attempt, from an anonymization-network IP addressAWS

Times are Pacific Daylight Time (UTC−7).

Are you affected by PHP2Shell?

You are IF any PHP that serves web requests is older than the fixed release for its branch, or is a vendor package that DOES NOT carry the fix yet.

PHP branchSupport statusFixed inWhat to do
8.5Active support8.5.12Update now
8.4Active support8.4.27Update now
8.3Security fixes only8.3.36Update now
8.2Security fixes end Dec 31, 20268.2.35Update now, then plan a move to 8.4 or 8.5
8.1, 8.0, 7.4End of lifeNo official release; source-only backports from PHPInstall your distro’s, panel’s or LTS vendor’s backported package, or upgrade
7.3 and olderEnd of lifeNothing from PHPUse a vendor backport if one exists; otherwise upgrade or take the site offline

Where PHP hides

Most teams find more copies than they expect! Check the following:

  • The marketing site or blog, often WordPress on a VPS or managed host
  • Container images such as php, wordpress, drupal or nextcloud, which bake in their own PHP
  • Control panels like cPanel, Plesk and DirectAdmin, which ship their own PHP builds
  • Managed platforms: Laravel Forge, Vapor or Cloud, WP Engine, Kinsta, Pantheon, AWS Elastic Beanstalk or Lightsail, Google App Engine, Azure App Service
  • Vendor appliances and tools; Palo Alto Networks, for one, lists PAN-OS and Panorama as affected, and the Dutch NCSC keeps a list of products that bundle PHP
  • Internal dashboards, admin panels and old intranet apps
  • Developer laptops running XAMPP, MAMP, Laragon or Homebrew PHP

The version-number trap

Linux distros and control panels usually backport the fix without changing PHP’s version number. So php -v can look old on a patched server, and look identical on a fixed and an unfixed one. Check the full package string or build date instead:

Platformphp -v showsFixed package or buildAdvisory
Ubuntu 24.048.3.68.3.6-0ubuntu0.24.04.13USN-8948-1
Ubuntu 22.048.1.28.1.2-1ubuntu2.28USN-8948-1
RHEL 9 default PHP8.0.30php-8.0.30-8.el9_8.1RHSA-2026:87151
RHEL 8 php:7.4 module7.4.33php-7.4.33-8.module+el8.10.0+25117+30337ccaRHSA-2026:87080
Plesk end-of-life builds7.4.33, 8.0.30, 8.1.34Same version, build dated Oct 21, 2026Plesk

These examples come from Digital Applied’s vendor-by-vendor table, which covers many more distros, panels and hosts.

How to check your servers for PHP2Shell in 30 minutes

Aim for one line in a spreadsheet for every place PHP runs, with “patched” proven by a package string or image tag rather than by php -v.

1. List everything that might run PHP

Websites and subdomains, servers and VMs, containers and Kubernetes workloads, hosting and panel accounts, vendor appliances and internal tools. From outside, the site’s response headers are a hint at best, since many sites hide them.

2. Debian and Ubuntu: list PHP packages and look for the fix

Check each PHP package’s full version string, and look for both CVEs in its changelog. If your package manager still lists PHP updates, you aren’t patched yet.

On packages from the popular Sury (ondrej/php) repository, the CVE note can sit one entry below the top of the changelog.

3. RHEL, AlmaLinux, Rocky and Amazon Linux: check the package changelog

Look for both CVEs in the changelog of your PHP packages, such as php-common, or php8.4-common on RHEL 10. If you install PHP from the Remi repository, check its status: it shipped no update on release day.

4. Find the PHP that actually serves your sites

php -v reports the command-line binary, which may not be what PHP-FPM or Apache runs. Also compare process start times with when the fixed package was installed: anything started earlier is still running old code.

5. Containers

The official php images are fixed in tags 8.5.12, 8.4.27, 8.3.36 and 8.2.35, and no 8.1-or-older tags are maintained. Check running containers and search your repos and clusters for PHP-based images.

6. Managed hosting and platforms

You can’t patch these yourself, so get a written answer. This is what vendors reported on October 21–22 (AWS bulletin, Digital Applied); statuses change quickly, so confirm before relying on them.

PlatformVendor-reported statusYour action
AWS Elastic BeanstalkUpdated PHP 8.2–8.5 platform versions releasedAutomatic with Managed Platform Updates; otherwise update the platform version
AWS LightsailUpdated blueprints; running instances aren’t updated in placeCreate a new instance from the updated blueprint and migrate
AWS Lambda (custom PHP runtime)Customer-managedRebuild with patched PHP and redeploy
Google App Engine, Cloud RunSome workloads patched automaticallyRedeploy
Azure App Service (Linux)Fixed on the Latest and Standard channels; Extended gets it lastCheck your channel
Laravel ForgeAutomatic security updates don’t patch PHP; no patch for 8.0 or 8.1Run Update PHP yourself
Laravel VaporRuntimes for 8.2–8.5 updatedRedeploy
WP Engine, Pantheon, Laravel CloudProduction sites patchedConfirm, including non-production
KinstaPatches rolling out for 7.4 through 8.5Confirm your site is done
cPanel, Plesk, DirectAdminFixed builds shipped Oct 21, including old-branch backportsRun the panel update and restart PHP

A message you can send your host: “Is the PHP serving [site] patched for CVE-2026-109618 and CVE-2026-109619? Which package or build is it running, and when were its workers restarted?”

7. Laptops and dev machines

List every PHP install on each machine, including Homebrew versions on Macs; Homebrew’s [email protected] has no fix. On Windows, look for XAMPP, WampServer, Laragon or a loose php.exe.

8. Record what you found

Copy this tracker into a spreadsheet and add one row per place PHP runs. The example row shows the level of proof to aim for.

AssetInternet-facing?How PHP runsPackage, build or image tagFix confirmed byWorkers restarted atOwner
Example: marketing site (WordPress)YesPHP-FPM on Ubuntu 24.04php8.3-fpm 8.3.6-0ubuntu0.24.04.13Changelog lists both CVEsOct 23, 09:40Ops lead

How to fix PHP2Shell

Patch, restart, verify: internet-facing servers first, with Apache mod_php and ARM64 hosts at the top of the list. PHP is clear that updating is the only complete fix.

  1. Update. Install the fixed PHP package from your distro, panel or host, and rebuild containers on the fixed images.
  2. Restart, don’t reload. Restart every PHP-FPM pool, Apache or LiteSpeed server and FrankenPHP service, plus long-running PHP processes such as queue workers, so nothing keeps the old binary loaded.
  3. Verify. Re-run checks 2–5 above and record the package string or image tag and the worker start time for each system.
  4. Isolate what you can’t patch. Take it offline or restrict it to a VPN or IP allowlist, as CISA and CERT-EU advise. CISA says the same for anything on PHP 8.1 or older that has no vendor backport.

Stopgaps if you can’t patch yet

These settings from PHP’s advisory narrow specific attack paths. None of them makes a server safe, and each needs a full PHP restart to take effect.

Setting or controlHelps againstLimits
Set session.upload_progress.enabled to 0 in php.ini, the FPM pool or server configKnown session paths of CVE-2026-109619, and the Oct 23 variantNothing for CVE-2026-109618 or other variants; setting it from app code or a .user.ini file doesn’t apply it
Set post_max_size to 8M on sites without uploads or 32M with uploads, keep upload_max_filesize below it, and add proxy limits on body size and on field, part and header countsCVE-2026-109618Reduces exposure only
Set memory_limit to -1 where apps can’t override it, using php_admin_valueCVE-2026-109618’s predictable triggerReal allocation failures still reach the bug, and unlimited memory invites denial of service; pair it with a container or cgroup memory limit
On PHP 8.5 only, set fatal_error_backtraces to 0One path of CVE-2026-109619That path only
WAF rules from Cloudflare, AWS WAF or Google Cloud ArmorKnown exploit patternsNew variants and traffic that bypasses the WAF

Once you’ve patched, restore a normal memory_limit and post_max_size. PHP suggests keeping session upload progress off until its next regular release unless your app uses it.

Were you already hit by PHP2Shell?

Patching doesn’t remove an attacker who got in first, so check every server that ran unpatched PHP on the internet since October 17. No official indicators of compromise have been published, so look for behaviour. Any one of these signs is a reason to dig deeper, though none proves an attack on its own:

  • Bursts of PHP or Apache worker crashes (segfaults, SIGSEGV, SIGABRT, “exited on signal”)
  • Memory errors at request startup, logged as ... in Unknown on line 0
  • Odd multipart POSTs to pages that never take uploads, followed by memory errors or repeated 500s; oversized or malformed PHPSESSID cookies
  • New or changed .php files in web roots, or any PHP file in an upload folder
  • The web user launching shells, curl, wget, nc, python or perl, or opening outbound connections
  • New cron jobs, systemd timers, user accounts or SSH keys

Expect some noise: WordPress and plugin auto-updates also change .php files, so compare any changed files with your update history.

To keep watching, log every program the web user starts, for example with Linux’s audit system, and forward logs off the server so an attacker can’t edit them. Baseline first, since image tools such as convert or gs can be legitimate.

If something looks wrong

  1. Cut the server off from the internet, but don’t wipe it yet: snapshot the disk and copy the logs somewhere safe.
  2. Rotate every secret the web user could read: database passwords, API keys, .env files, app keys and salts (Laravel APP_KEY, WordPress salts), session secrets and cloud credentials. Then invalidate active sessions. These bugs can leak worker memory, so rotate even on suspicion.
  3. Rebuild from a clean, patched image rather than cleaning the old server in place.
  4. Check your obligations to customers, regulators, investors and insurers if data may have been exposed, and bring in incident-response help if you need it.

Lessons from PHP2Shell for small teams

The patch itself was the easy part this week; the hard part was finding every copy of PHP and knowing who was responsible for updating it. Use PHP2Shell to set that up before the next one:

  • Keep a living inventory of every runtime you depend on, container images included, with a named owner for each.
  • Write down who patches what. You, your control panel or your host, and how fast. Laravel Forge users learned this week that its automatic security updates don’t cover PHP.
  • Get off end-of-life PHP. Move off 8.1 and older now, and off 8.2 before its security support ends on December 31, 2026; 8.4 or 8.5 is the better target.
  • Automate security updates where it’s safe (unattended-upgrades on Debian and Ubuntu, dnf-automatic on RHEL) and automate the restart that has to follow.
  • Put a WAF or CDN in front of public PHP apps. Cloudflare, AWS WAF and Google Cloud Armor shipped rules quickly; they buy time but don’t replace patching.
  • Reconsider mod_php. It was the highest-risk setup here, so if you still run it, evaluate PHP-FPM behind a reverse proxy.
  • Measure your time to patch, from advisory to fixed everywhere, and aim for under 24 hours on critical issues.

This post reflects vendor statements as of October 23, 2026. Fixes are still rolling out, so check the sources below for the latest status.

Want a second pair of eyes on your stack? Get in touch with Testify Labs, or read more posts on our blog.

PHP2Shell FAQ

Does updating WordPress, Laravel or Drupal fix PHP2Shell?

No. The flaws are in the PHP runtime, so the PHP that runs your app has to be updated. On managed hosting that’s your host’s job; on your own servers it’s yours.

I updated PHP. Why does php -v still show an old version?

Linux distros and control panels often backport the fix without changing the version number. Compare the full package string with your vendor’s advisory, as in steps 2 and 3 above.

Is turning off session.upload_progress enough?

No. It blocks some known paths for CVE-2026-109619 and does nothing for CVE-2026-109618. Treat it as a stopgap until you can patch.

Does a web application firewall protect me?

Partly. WAF rules from Cloudflare, AWS and Google block known attack patterns, but they can miss new variants and any traffic that reaches PHP without passing through the WAF.

Is there a fix for PHP 8.1, 8.0 or 7.4?

Not as an official PHP release. The PHP security team published source-only backports, and many distros, control panels and long-term-support vendors ship backported packages. Otherwise, upgrade to 8.4 or 8.5.

I’m on a managed host. Do I need to do anything?

Usually less, but not nothing. Get written confirmation that your PHP is patched and its workers restarted, and check anything you manage yourself, such as Laravel Forge servers, Lambda functions or containers.

Is PHP2Shell being exploited?

Yes. Amazon logged an attempt on October 17, before the fix shipped, and several security firms reported attacks on release day. As of October 22, neither CVE was in CISA’s Known Exploited Vulnerabilities catalog.

Updates

  • October 27, 2026: Fixed the links in “In this guide”.
  • October 23, 2026: Published.

Sources