Security

PHP2Shell (CVE-2026-109618 & CVE-2026-109619): Complete Guide

By ZeeDev Innovations Updated 18 min read

PHP2Shell complete security guide banner
In this article

Understanding PHP2Shell: Everything You Need to Know About CVE-2026-109618 and CVE-2026-109619

What is PHP2Shell?

PHP2Shell is the name the security community gave to a pair of critical remote code execution (RCE) vulnerabilities in the PHP interpreter itself, disclosed by the PHP project on October 21, 2026:

  • CVE-2026-109618: remote code execution through memory corruption during out-of-memory (OOM) handling.
  • CVE-2026-109619: remote code execution through stale global state, a use-after-free that crosses from one request to the next.

The name comes from the research community: Wiz and Calif both use “PHP2Shell” in their write-ups, and the label stuck once news of the bugs spread.

What makes PHP2Shell different from the usual “plugin X has a bug” story is where the flaw lives. It sits in the PHP engine’s request handling, the code that parses an incoming request before any of your PHP files execute. That means every framework and CMS built on PHP inherits the exposure, no matter how well its own code is written. Researchers demonstrated unauthenticated code execution against current releases of WordPress, Drupal, Joomla, Magento, Laravel and Symfony.

With PHP powering a large share of the web (Wiz estimates roughly 70% of websites), this is one of the most significant PHP security events in years.

PHP2Shell at a glance

CVE-2026-109618CVE-2026-109619
Official titleRCE via OOM corruptionRCE via stale global state
PHP advisoryGHSA-w8hw-w9fx-j79wGHSA-6wmf-4rv5-p3rp
SeverityCritical, CVSS v4.0 9.2Critical, CVSS v4.0 9.2
CVSS v3.1 score (NVD)9.88.1
Authentication neededNoneNone
User interactionNoneNone
AffectedPHP < 8.2.35, < 8.3.36, < 8.4.27, < 8.5.12, plus all end-of-life branchesSame
Fixed in8.2.35, 8.3.36, 8.4.27, 8.5.12Same
ReleasedOctober 21, 2026October 21, 2026

The CVSS v4.0 vector for both is AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H. In plain English: attackable over the network, no login, no user interaction, full loss of confidentiality, integrity and availability. The “AC:H / AT:P” parts mean exploitation depends on certain conditions being present, which is why it scores 9.2 rather than 10. (A “10.0” figure that circulated before the release was incorrect, according to the PHP Foundation.)

What happened: the PHP2Shell timeline

PHP2Shell’s disclosure did not go as planned. A coordinated release was in progress when details leaked, forcing everyone to move faster.

Date (2026, UTC)Event
Before Oct 20Independent research teams, including Wiz and Calif, report the flaws privately to the PHP security team. Both teams reportedly used AI models to help find the bugs. A coordinated fix is scheduled for October 22.
Oct 17Amazon (AWS) observes an exploitation attempt against a honeypot, four days before public disclosure.
Oct 20, ~15:00The CVE IDs leak on forums and social media. A proof-of-concept video is published prematurely and the “PHP2Shell” name spreads.
Oct 20, 19:30The PHP project issues an advance notice: two critical vulnerabilities, both CVSS v4.0 9.2, with the release brought forward by a day.
Oct 21, ~14:00PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 are released alongside a “Critical remote code execution vulnerabilities, update now” advisory. Source-only backports are published for the end-of-life 7.4, 8.0 and 8.1 branches.
Oct 21Cloudflare reports thousands of attack attempts in the hours before the announcement, rising to millions by the end of the day. Government agencies including the UK NCSC, CERT-EU and the US NSA urge operators to patch or take systems offline. Some hosts and government platforms temporarily disconnect services while they patch.
Oct 23PHP publishes an informational follow-up about a separate, less likely RCE vector in session upload progress (to be tracked as CVE-2026-115560) and recommends setting session.upload_progress.enabled=0 until the next regular bugfix release.
Oct 26CISA adds both CVEs to its Known Exploited Vulnerabilities catalog, with an October 29 remediation deadline for US federal agencies.
Oct 26Updated Windows builds (8.x.y-1) ship for an unrelated Brotli library fix. The PHP runtime versions are unchanged.

Exploitation status (as of November 9, 2026): exploitation in the wild is confirmed. CISA added both CVEs to its Known Exploited Vulnerabilities catalog on October 26, and watchTowr reports seeing both exploited. Multiple vendors report large-scale scanning and attacks, and researchers, including CrowdStrike, have built working exploits in the lab. Not every attempt succeeds, because success depends on server configuration. Treat this as an actively exploited vulnerability and patch now.

Why it happened: the root cause explained

Both bugs come from the same old design pattern inside the Zend Engine, PHP’s core.

The shared root cause: “bailing out” without cleaning up

When PHP hits a fatal error in the middle of handling a request (running out of memory, exceeding max_execution_time, or the client disconnecting), it does not unwind step by step. It performs an immediate jump out of the current code path (a C longjmp, triggered by zend_bailout()). That is fast, but it means any data structure that was half-built at that moment is left as-is.

For years this was considered harmless. PHP2Shell showed that an attacker who can choose the exact moment of the fatal error can leave internal memory in a state they control.

CVE-2026-109618: memory corruption during out-of-memory handling

PHP parses incoming POST data into arrays before your script runs. While adding a new key to an internal hash table, the engine updated the table’s element count before finishing allocating the key. If the request runs out of memory precisely between those two steps, the table now contains a “slot” that looks valid but points to memory that was never properly set up.

During cleanup of that same failed request, PHP walks the table and uses the stale entry. Because PHP’s memory allocator reuses freed blocks in a predictable order, an attacker can pre-fill that memory with crafted data, such as a fake array whose destructor points to a system command function. The result is code execution from a single anonymous POST request, before any application code loads.

Researchers also showed the bug can leak fragments of server memory back to the attacker, for example inside an oversized session cookie.

CVE-2026-109619: stale global state shared between requests

PHP worker processes (in PHP-FPM, Apache mod_php and similar setups) handle many requests in a row. Some engine-level state, around serialization and session handling, is kept in global variables that live across requests.

If a fatal error interrupts a request at the wrong point, one of those globals can keep pointing at memory that has already been freed. The next request handled by the same worker then uses that dangling pointer (a classic use-after-free). The attack is two-stage: one request “poisons” the worker, and a follow-up request triggers the payload.

Why it went unnoticed for so long

These code paths are old. The earliest affected path researchers found dates back to PHP 5.4, and the hash-table attack path works on PHP 7.3 and later. Bugs that only appear when memory runs out at an exact instruction are extremely hard to find by hand, which is one reason modern, AI-assisted research surfaced them now.

Who is affected?

Any server running an unpatched PHP version that serves web requests. That includes:

  • PHP-FPM (Nginx, Apache with proxy_fcgi, most modern hosting)
  • Apache mod_php
  • php-cgi
  • LiteSpeed (LSAPI)
  • FrankenPHP

And by extension, every application on top of PHP: WordPress, WooCommerce, Drupal, Joomla, Magento/Adobe Commerce, Laravel, Symfony, CodeIgniter, PrestaShop, Moodle, custom PHP apps, and internal admin panels.

Vulnerable versions:

PHP branchStatusWhat to do
8.5SupportedUpgrade to 8.5.12+
8.4SupportedUpgrade to 8.4.27+
8.3Security-only (until Dec 31, 2027)Upgrade to 8.3.36+
8.2Security-only (EOL Dec 31, 2026)Upgrade to 8.2.35+, and plan a move to 8.4/8.5
8.1, 8.0, 7.4End of lifeNo official binaries. Source-only backports exist. Upgrade the PHP branch, or get a patched build from your OS vendor or host
7.3 and olderEnd of lifeNo fix. Treat as vulnerable and upgrade

A note on configuration: exploitation is not equally easy everywhere. CrowdStrike’s analysis found that the simplest route for CVE-2026-109618 needs memory_limit to be less than about four times post_max_size. PHP’s stock defaults (memory_limit=128M, post_max_size=8M) do not meet that condition, but many real-world servers raise post_max_size for uploads (for example 64M or 100M), which does. Other attack paths, including multipart uploads and the CVE-2026-109619 chain, have different preconditions. Do not rely on your configuration as protection. Patch.

Distribution packages: Linux distributions (Debian, Ubuntu, RHEL/Alma/Rocky, Alpine and others) often backport fixes without changing the upstream version number. A server reporting “8.1.2” may be patched if your vendor shipped a fixed package. Check your vendor’s security tracker for CVE-2026-109618 and CVE-2026-109619 rather than relying on the version string alone.

Impact: what an attacker can do

A successful PHP2Shell exploit gives the attacker code execution as the user your PHP workers run as (often www-data, apache or nginx). From there, typical follow-on activity includes:

  • Installing web shells for persistent access
  • Stealing secrets: database credentials in wp-config.php or .env, API keys, cloud credentials
  • Data theft: customer records, orders, user accounts and session data
  • Defacement and SEO spam: injected links, cloaked pages, malicious redirects
  • Payment skimming on e-commerce sites (Magecart-style)
  • Cryptomining or using your server as a botnet node
  • Lateral movement into internal networks and other services
  • Memory disclosure that can expose secrets even without full code execution (shown by researchers for CVE-2026-109618, and listed in the PHP advisory for CVE-2026-109619)

For businesses, that translates into downtime, breach-notification obligations, lost customer trust, blacklisting by search engines and browsers, and incident-response costs.

How to check if your server is vulnerable

Step 1: Inventory every PHP installation

Don’t stop at your main website. List every place PHP runs: staging and test copies, old microsites, internal tools, admin panels, containers, and anything a contractor set up years ago. Prioritize internet-facing systems first.

Step 2: Check the version your web server actually uses

The command-line PHP (php -v) can be a different build from the PHP that serves web traffic. Check the web SAPI directly:

# CLI version (may differ from the web version)
php -v

# PHP-FPM version
php-fpm -v          # or php-fpm8.3 -v, php-fpm84 -v, etc.

# Which PHP-FPM services are running
systemctl list-units --type=service | grep -i php

Or create a temporary file in the web root, load it in a browser, then delete it immediately:

<?php echo PHP_VERSION, ' ', PHP_SAPI;

On WordPress, go to Tools > Site Health > Info > Server to see the PHP version. Treat this as a starting point, and confirm with your host.

Step 3: Check package-level patch status

# Debian / Ubuntu
apt list --installed 2>/dev/null | grep -i php

# RHEL / Alma / Rocky / Fedora
rpm -qa | grep -i php

# Containers
docker run --rm <your-image> php -v

Compare against your distribution’s security advisories for both CVEs.

Step 4: Review exposure-related settings

php -i | grep -E "^(memory_limit|post_max_size|upload_max_filesize|session.upload_progress.enabled|Loaded Configuration File)"

php -i shows the command-line settings, which can differ from the web server. Also remember that post_max_size can be overridden per directory (.htaccess, virtual host, FPM pool), so check those too.

How to detect exploitation attempts

PHP2Shell is stealthy. In CrowdStrike’s testing, a successful exploit returned an ordinary HTTP 200, did not crash the worker, and wrote nothing to application logs. Look for these signals instead:

1. “Unknown on line 0” memory errors in the web server or PHP-FPM error log. This is the strongest indicator. It means memory ran out while PHP was parsing the request, before any script was running:

PHP Fatal error:  Allowed memory size of ... bytes exhausted (tried to allocate ... bytes) in Unknown on line 0

Search for it:

grep -R "in Unknown on line 0" /var/log/nginx/ /var/log/apache2/ /var/log/httpd/ /var/log/php*-fpm.log 2>/dev/null

2. Unusual POST requests: very large URL-encoded or multipart bodies with deeply nested field names (for example long strings followed by [x]), especially to URLs that don’t normally accept POSTs.

3. Oversized or malformed PHPSESSID cookies in responses, which may indicate memory leakage.

4. Bursts of HTTP 500s or unexplained PHP worker restarts following large requests (behavior varies by setup).

5. Post-exploitation signs:

  • PHP or web-server processes spawning shells (sh, bash), curl, wget, nc or python
  • New or modified .php files in upload, cache or theme directories
  • New cron jobs, SSH keys or system users
  • Unexpected outbound connections from the web server
  • New WordPress admin accounts or unexpected plugin installs

How far back to look: AWS recorded attempts from October 17, 2026, so review logs from at least that date. Preserve logs before they rotate.

Important: patching stops new attacks but does not remove anything an attacker already planted. If you find signs of compromise, follow your incident-response process: isolate the server, preserve evidence, rotate credentials and rebuild from known-good sources.

How to patch and protect against PHP2Shell

1. Upgrade PHP

Move to a fixed release: PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or newer.

# Debian / Ubuntu (including the ondrej/php PPA)
sudo apt update && sudo apt install --only-upgrade 'php*'

# RHEL / Alma / Rocky (Remi or AppStream modules)
sudo dnf upgrade 'php*'

# Alpine
apk update && apk upgrade 'php*'

# Docker: pull the patched official image tag and rebuild
docker pull php:8.4-fpm   # then rebuild and redeploy your images

On shared or managed hosting (cPanel, Plesk, managed WordPress), switch to a patched version in the control panel or open a support ticket. Ask your host for written confirmation that the PHP serving your site includes the October 21 fixes.

2. Restart every PHP worker

This step is easy to miss. Long-running workers keep the old, vulnerable code in memory until they restart.

sudo systemctl restart php8.3-fpm   # repeat for each installed version
sudo systemctl restart apache2      # or httpd, if you use mod_php

Also restart LiteSpeed, FrankenPHP, Octane/RoadRunner/Swoole workers, and any container running PHP.

3. Verify the fix

Load your temporary version-check page again (then delete it), or confirm the FPM version. Don’t assume the upgrade took effect until you’ve checked the SAPI serving traffic.

4. Apply the follow-up hardening

Per the PHP project’s October 23 notice, set this in php.ini or your FPM pool (not via ini_set() or .user.ini) until the next regular bugfix release, and restart workers:

session.upload_progress.enabled = 0

5. Upgrade off end-of-life PHP

If you were on PHP 8.1 or older, this incident is the push to move to a supported branch (8.4 or 8.5 ideally). PHP 8.2 itself reaches end of life on December 31, 2026.

Temporary mitigations if you cannot patch yet

If you truly cannot upgrade immediately, the PHP advisories list measures that reduce, but do not eliminate, exposure. None of them is a complete mitigation.

For CVE-2026-109618 (OOM corruption):

  • Keep post_max_size low: around 8M for apps that don’t need uploads, or 32M if they do, with upload_max_filesize below it.
  • Setting memory_limit = -1 (enforced via php_admin_value) removes the controllable memory-limit failure, but a real allocation failure can still reach the vulnerable path. Use a container or cgroup memory limit to protect the host. Avoid RLIMIT_AS/RLIMIT_DATA, which can hit the vulnerable path.
  • Enforce request limits at your reverse proxy or WAF: body size, number of fields, multipart parts, header count and nesting depth. Lower max_input_nesting_level. Block multipart uploads where your app doesn’t use them.

For CVE-2026-109619 (stale state):

  • Set session.upload_progress.enabled = 0 and restart workers.
  • On PHP 8.5, set fatal_error_backtraces = 0.
  • Setting pm.max_requests = 1 in PHP-FPM gives each request a fresh worker (at a performance cost).

Network and operational measures:

  • Put internet-facing PHP behind a WAF with rules for PHP2Shell (major providers including Cloudflare have shipped them).
  • Restrict access to admin panels and internal tools by IP or VPN.
  • If a system can’t be patched or adequately protected, follow official guidance (NCSC, CERT-EU, NSA) and take it offline until you can.

WordPress and website-owner checklist (including SEO)

PHP2Shell is a server-level issue, so many website owners won’t patch it themselves. Here’s what to do and check:

Security

  • Understand that WordPress, theme and plugin updates do not update PHP, and a security plugin cannot replace the PHP fix.
  • Ask your host which PHP version serves your site and get written confirmation it includes the October 21, 2026 fixes.
  • Check every site you own: old blogs, landing pages, staging copies.
  • Review admin users, recently changed files and installed plugins for anything unexpected.
  • Rotate passwords, database credentials and API keys if you see any signs of compromise.
  • Scan backups for malware before restoring them.

SEO protection during and after patching

  • If you must take the site down temporarily, return 503 Service Unavailable (ideally with a Retry-After header) and a short informational page. Search engines treat a brief 503 as temporary.
  • Avoid site-wide noindex, 404 or 410 responses during maintenance. They can cause pages to drop from search results.
  • Keep robots.txt reachable.
  • After patching, confirm key pages return HTTP 200, and that redirects, canonical tags and noindex settings are as intended.
  • Test critical journeys: forms, login, checkout and file uploads (new upload limits may break them).
  • Watch Google Search Console for security issues, manual actions, spam pages or crawl errors over the following weeks.
  • Note that an HTTPS padlock says nothing about whether PHP is patched.

Long-term lessons from PHP2Shell

  1. Patch the platform, not just the app. Runtime and OS updates deserve the same urgency and process as CMS updates.
  2. Keep an accurate inventory. You can’t patch a forgotten staging server. Track every PHP version across every environment.
  3. Stay on supported versions. End-of-life PHP gets no official fixes. Budget for regular upgrades.
  4. Automate updates and restarts. Unattended security upgrades plus scheduled worker restarts close the window attackers rely on.
  5. Defense in depth. WAFs, request-size limits, least-privilege service accounts, egress filtering and endpoint monitoring all limit what one engine bug can do.
  6. Log and monitor. The best PHP2Shell indicator lived in the web server error log. Centralize logs and alert on anomalies.
  7. Expect faster discovery. AI-assisted research is surfacing deep, old bugs faster. Assume more of these are coming and keep your patch process tight.

Frequently asked questions about PHP2Shell

What is PHP2Shell?

PHP2Shell is the common name for two critical remote code execution vulnerabilities in the PHP engine, CVE-2026-109618 and CVE-2026-109619, disclosed on October 21, 2026. Under certain configurations they let an unauthenticated attacker execute code on a PHP web server with crafted HTTP requests.

Which PHP versions are affected by CVE-2026-109618 and CVE-2026-109619?

All PHP versions before 8.2.35, 8.3.36, 8.4.27 and 8.5.12 are affected, as are end-of-life branches such as 8.1, 8.0, 7.4 and older.

Which PHP versions fix PHP2Shell?

PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released on October 21, 2026, and any later version. Your Linux distribution may also ship backported fixes under a different version number.

Is PHP2Shell being exploited in the wild?

Yes. CISA added both CVEs to its Known Exploited Vulnerabilities catalog on October 26, 2026, and watchTowr reports seeing both exploited. Attempts began before public disclosure (AWS recorded one on October 17, 2026), and Cloudflare reported millions of attempts by October 21.

Does updating WordPress, Drupal or Laravel protect me?

No. The flaws are in PHP itself and trigger before your application code runs. You must update PHP and restart its workers.

Is my site safe if I use a WAF?

A WAF with PHP2Shell rules reduces risk but does not replace patching. Rules can be bypassed and don’t cover every attack path.

Am I safe if I use PHP’s default memory_limit and post_max_size?

Defaults make the simplest attack path harder, but other paths exist and many servers change these settings. Configuration is not a substitute for patching.

How do I know if my server was already compromised?

Look for “Allowed memory size … exhausted … in Unknown on line 0” errors in your web server logs, unexpected PHP files, new admin users, new cron jobs, PHP processes spawning shells, and unusual outbound connections, starting from at least October 17, 2026.

I’m on shared hosting. What should I do?

Ask your host to confirm in writing that the PHP version serving your site includes the October 21, 2026 fixes. Switch to a patched version in your control panel if one is available.

What is CVE-2026-115560?

It’s a separate, lower-likelihood RCE vector in PHP’s session upload progress feature, announced on October 23, 2026. Until it’s fixed in the next regular release, PHP recommends setting session.upload_progress.enabled=0. Keep the October 21 updates installed regardless.

Does PHP2Shell affect PHP CLI scripts and cron jobs?

The attack paths target PHP handling web requests (FPM, mod_php, CGI, LiteSpeed, FrankenPHP). CLI scripts aren’t exposed to HTTP input in the same way, but you should upgrade every PHP installation anyway.

Sources


Need help securing your PHP applications?

ZeeDev Innovations helps businesses audit, patch and harden PHP, WordPress and Laravel applications, from emergency patching and compromise checks to long-term upgrade plans. Contact our team for a PHP2Shell security review.

Want help putting this into practice?

Check how your website scores on Google for free, or book a free 30-minute call with our team.

ZeeDev Innovations empowers businesses to transform bold visions into digital reality through cutting-edge technology, smart design, and continuous innovation.

Contact Us

Copyright © 2026 Zeedevinnovations. All Right Reserved.

Chat with us