Guides

PHP2Shell (CVE-2026-109618): How to Check and Patch Your Server

By Nehal Azhar, Zoho Certified Consultant / AWS Certified Solutions Architect · Published · Updated

If your site or app runs PHP 5.4 through 8.5.11, upgrade to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35 now and restart every PHP worker, because two critical bugs nicknamed PHP2Shell let an attacker run code on the server without logging in. The flaws are in PHP itself, so WordPress, Laravel and any other PHP app are exposed. Also set session.upload_progress.enabled=0, because a third session bug disclosed on 23 October has no patch yet.

What is PHP2Shell?

PHP2Shell is the name for two remote code execution bugs that PHP fixed on 21 October 2026. Each is rated 9.2 (critical) on CVSS v4.0:

  • CVE-2026-109618: when PHP runs out of memory partway through reading a request, the request data can be left half-built, and PHP's clean-up then treats it as valid.
  • CVE-2026-109619: state from one request can survive after its memory is freed, so a later request on the same PHP worker uses stale data before it is reset.

The demonstrated attacks need no login and run before your code, so your app's own checks cannot stop them.

Am I affected?

You are affected if any PHP version from 5.4 up to 8.5.11 serves web requests for you. That covers Apache with mod_php, PHP-FPM behind Nginx or Apache, php-cgi, FrankenPHP and LiteSpeed. PHP's advisory says the risk is highest for mod_php.

These are the first fixed versions on each supported branch:

  • PHP 8.5: 8.5.12
  • PHP 8.4: 8.4.27
  • PHP 8.3: 8.3.36
  • PHP 8.2: 8.2.35 (this branch reaches end of life on 31 December 2026)
  • PHP 8.1 and older: no official release. PHP published minimal source backports for 7.4, 8.0 and 8.1, and some Linux vendors ship their own, but the safe path is to move to 8.2 or newer.

Apps built only on Node, Deno or Python, such as a typical Lovable, Bolt or Next.js app, do not run PHP. But a WordPress marketing site, a hosting control panel or a firewall admin page may still run PHP.

How do I check which PHP version my site runs?

Check the PHP that serves web requests: the php command can be a different install from the one your web server uses.

On your own server

# The FPM binary the web server talks to (adjust the version suffix)
sudo php-fpm8.3 -v      # RHEL/Alma/Rocky: sudo php-fpm -v

# Debian/Ubuntu: confirm the package includes the fix
apt-get changelog php8.3-fpm | grep -E "CVE-2026-109618|CVE-2026-109619"

# RHEL, Alma, Rocky
rpm -q --changelog php-fpm | grep -E "CVE-2026-109618|CVE-2026-109619"

Distributions often backport fixes without changing the version number, so trust the changelog. Google, citing PHP's security team, warns some third-party RPM mirrors lag behind, so use your distribution's official repositories.

On WordPress

Go to Tools, then Site Health, then the Info tab, and open Server to see the PHP version WordPress is actually running.

In Docker

docker run --rm --entrypoint php your-image:tag -v

How do I patch it?

  1. Upgrade PHP to a fixed version from your distribution or official repository. On Debian or Ubuntu: sudo apt update && sudo apt upgrade.
  2. Restart the PHP that serves web traffic, for example sudo systemctl restart php8.3-fpm or sudo systemctl restart apache2 (httpd on RHEL). Until workers restart, the old vulnerable code stays loaded.
  3. For containers, rebuild images on a patched base image and redeploy, then make sure no old containers or workers are still running.
  4. For anything on PHP 8.1 or older, plan the move to a supported branch. PHP 8.4 or 8.5 gives you the longest runway.

If you suspect a server was already attacked, take a memory capture before you restart it if you can. Restarting clears the evidence an investigator would use.

What if I'm on shared or managed hosting?

On shared hosting your host runs PHP, so the upgrade is theirs to do. Ask support whether they applied PHP's 21 October fixes and the 23 October session setting. SiteGround, for example, published that it patched all servers the same day; don't assume yours did.

If you can choose a PHP version, pick 8.4 or 8.5. On Google Cloud, App Engine Standard on PHP 8.2 or newer was patched automatically and Cloud Run is patched where automatic base image updates are on. App Engine Flexible, GKE and anything else built from your own container images must be rebuilt and redeployed.

Patching PHP does not patch WordPress itself. Keep WordPress, themes and plugins updated and remove plugins you no longer use.

What can I do if I can't patch today?

PHP's advisory lists interim settings that reduce exposure but, in its words, do not make an installation safe. Put them in the main php.ini, the FPM pool or the Apache server config (php_admin_value/php_admin_flag), not .htaccess, .user.ini or ini_set(). Check nothing overrides them, then restart every worker.

; CVE-2026-109619 and the unpatched CVE-2026-115560
session.upload_progress.enabled = 0

; PHP 8.5 only
fatal_error_backtraces = 0

; CVE-2026-109618: stopgap only. Pair with a container or cgroup
; memory limit, and restore a finite value after patching.
memory_limit = -1

; Smaller requests: PHP suggests 8M without uploads, 32M with
post_max_size = 8M
upload_max_filesize = 4M
  • Don't cap memory with ulimit -v or systemd's LimitAS=/LimitDATA=. These make memory allocation fail, which is exactly the path the first bug needs. Use a cgroup limit such as systemd's MemoryMax= instead.
  • Enforce request size limits at the web server or proxy as well, for example Nginx's client_max_body_size.
  • Enable your WAF's rules for these CVEs, but Google calls those compensating controls only.
  • If a server can't be patched quickly, take it off the public internet or put it behind network-level access control such as zero-trust access, as Sophos recommends.

What about the newer CVE-2026-115560?

On 23 October PHP published an informational advisory about a further remote code execution path involving sessions. The 21 October releases do not fix it, and PHP will fix it in its next regular bugfix release.

PHP says it needs an unusual combination: session.serialize_handler configured as php_binary or php_serialize, then switched to php with ini_set() before session_start(), while session upload progress is still enabled.

The fix for now is the same setting as above, session.upload_progress.enabled = 0. If you already set it for CVE-2026-109619, PHP says you need to do nothing more. As of 26 October no exploitation had been reported.

How do I know if I was attacked?

Look for these signs, drawn from Datadog's and Google's detection guidance:

  • The strongest sign: a web server or PHP process (php-fpm, httpd, apache2, frankenphp) starting a shell or tool such as sh, bash, curl, wget or nc.
  • PHP error log lines such as Allowed memory size of ... bytes exhausted with Unknown on line 0, which means PHP failed before any script ran. A short burst of these can be enough.
  • Worker crashes, for example Apache's AH00052: child pid ... exit signal Segmentation fault (11), or a spike in PHP-FPM worker restarts.
  • Set-Cookie: PHPSESSID= values in responses that are far longer than normal (over 256 characters) or contain percent-encoded or binary data, which can mean memory is leaking.
  • Multipart POSTs with PHPSESSID or PHP_SESSION_UPLOAD_PROGRESS fields your app doesn't use.

Some attacks leave no crash or error at all, so a clean error log is not proof. If you find any of these signs, treat the server as compromised: isolate it, capture evidence, rotate every secret it held, and rebuild it from a clean image rather than patching in place. Our guide on rotating leaked API keys covers the rotation step.

Frequently asked questions

Is my WordPress site affected by PHP2Shell?

Yes, if it runs on PHP 5.4 through 8.5.11 and the host has not patched or mitigated it. The bug is in PHP itself, so it does not matter which plugins or theme you use. Check the version under Tools, Site Health, Info, Server, and ask your host whether they applied the 21 October fixes.

I upgraded PHP. Why am I still vulnerable?

Usually because the running workers were not restarted, so the old code is still loaded in memory. Restart PHP-FPM or Apache, then check the version the web server reports. Also check that you upgraded the PHP your web server uses, not a separate command-line install.

Does a WAF or Cloudflare protect me?

It can block known attack patterns and buys time, but Google describes WAF rules as compensating controls only. Patch PHP and restart workers as well.

Are apps built with Lovable, Bolt or Next.js affected?

Not directly, because they run on Node, Deno or other runtimes rather than PHP. Check other parts of your setup that may use PHP, such as a WordPress site, a hosting control panel or a network appliance's admin page.

Sources

Checked 31 Oct 2026. Provider settings and limits change, so confirm against the linked documentation.

Keep going

Want a second pair of eyes? Book the free audit call.

A free 30-minute review of your AI-built app, then a written fix plan and a quote.