← All advisories
CVE-2026-109618criticalCode execution2026-10-21

php2shell (CVE-2026-109618, CVE-2026-109619): unauthenticated remote code execution in PHP itself

Two bugs in how the PHP runtime cleans up memory after a request ends abnormally can let an unauthenticated HTTP request run code as the web server's PHP worker. They affect every PHP install that serves web requests (PHP-FPM, mod_php, php-cgi, FrankenPHP, LiteSpeed). PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix them, and Cloudflare's WAF blocks known exploits by default, including on the Free plan.

01.

What it is

CVE-2026-109618 (GHSA-w8hw-w9fx-j79w), RCE via out-of-memory corruption: if PHP runs out of memory while setting up request data, it aborts with that data only partly initialized, and request cleanup then treats it as valid. PHP says full RCE was validated over HTTP against mod_php with default input and memory limits.

CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp), RCE via stale global state: request-owned state can survive after its memory is freed, and the next request on the same worker may use it before normal initialization resets it. That gives a heap use-after-free, memory disclosure and RCE with the worker's privileges.

PHP rates the risk highest for mod_php, where an unauthenticated request can trigger the attack before any application code runs. Your own code or plugins don't matter here: the flaw is in the runtime, so updating WordPress, Laravel or a plugin does not fix it.

Details leaked on October 20 before the coordinated release. Cloudflare reported seeing attack traffic and payloads being changed to get past its rules. NVD lists both CVEs as 'Received' (not yet analyzed) as of October 21, 2026.

Affected supported lines: 8.2 before 8.2.35, 8.3 before 8.3.36, 8.4 before 8.4.27 and 8.5 before 8.5.12. PHP 8.1 and older get no official releases. PHP published minimal source backports for 7.4, 8.0 and 8.1, and Cloudflare says PHP 5.4 and later are affected.

02.

How to check

  1. Run php -v on the server, or check phpinfo() or your host's control panel (cPanel: 'Select PHP Version' or 'MultiPHP Manager'). Note the version for the web server, not just the CLI, because they can differ.
  2. Shared and managed hosting: ask your host whether the PHP build serving your site includes the 21 October 2026 fixes. Distro packages (Debian, Ubuntu, RHEL) may backport the fix under an older version number, so check the package changelog.
  3. Behind Cloudflare: open Security > Security Analytics > Events and filter for the 'Generic Rules - Anomalous Execution' rule IDs to see blocked attempts. Paid plans should confirm the Cloudflare Managed Ruleset is deployed in block mode.
  4. Vercel and Netlify don't run PHP for typical Next.js or static sites. If you only use them, this doesn't affect you, unless a PHP backend, a WordPress site or a community PHP runtime sits somewhere else in your stack.
03.

How to fix

  1. Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35 (or your distro's patched package), then restart every PHP worker: php-fpm, Apache, FrankenPHP or LiteSpeed.
  2. On PHP 8.1 or older, move to a supported version or get a vendor backport. Until then, keep the site off the public internet if you can.
  3. Cloudflare: the WAF rules are on by default for Free customers (Managed Free Ruleset) and paid plans (Cloudflare Managed Ruleset), plus a new response rule in the Managed Response Firewall. Don't switch them off while you patch, and paid plans should make sure the Managed Ruleset is set to block. Cloudflare calls this defense in depth, not a replacement for the update.
  4. If you can't update yet, PHP lists partial measures that do NOT make you safe: memory_limit=-1 set with php_admin_value, a low post_max_size (8M without uploads, 32M with), session.upload_progress.enabled=0 in php.ini or the FPM pool (not ini_set or .user.ini), and on 8.5 fatal_error_backtraces=0. Restart workers after each change.
# Version used by the CLI (the web SAPI can differ, so also check phpinfo())
php -v
php-fpm -v 2>/dev/null; apachectl -M 2>/dev/null | grep -i php

# Debian/Ubuntu: is the patched package installed?
apt list --installed 2>/dev/null | grep -E '^php[0-9.]*-(fpm|cli|common)'
sudo apt update && sudo apt upgrade 'php*' && sudo systemctl restart php*-fpm apache2

# Stopgap only (php.ini or FPM pool, then restart workers):
# session.upload_progress.enabled = 0
# post_max_size = 8M
04.

Sources

The weekly email

One email a week. Only what changed.

New advisories, CVEs and fixes for Lovable, Bolt, v0, Replit, Base44 and Cursor apps. No roundups of things you already read.

Free. The list is new, so the first issues go out once there are readers. Unsubscribe from any email in one click. We never sell or share addresses.