Blogs>PHP2Shell Explained: CVE-2026-109618 and CVE-2026-109619 Patched After Pre-Disclosure Exploitation

PHP2Shell Explained: CVE-2026-109618 and CVE-2026-109619 Patched After Pre-Disclosure Exploitation

Simulations Labs
📅October 22, 2026
PHP2Shell Explained: CVE-2026-109618 and CVE-2026-109619 Patched After Pre-Disclosure Exploitation

PHP rarely breaks its release calendar. On October 21, 2026 it did, shipping PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 at 13:52 UTC to fix two flaws that let an unauthenticated attacker run code on the server. Researchers are calling the pair PHP2Shell. By the time the fix went out, attackers were already using it.

What is PHP2Shell?

PHP2Shell covers two CVEs, both rated 9.2 on CVSS v4.0 by the PHP project. Neither lives in a framework, a plugin or your code. They live in the engine.

CVE-2026-109618 is an out-of-memory bug. If PHP hits its memory limit at the wrong moment, an operation stops halfway and leaves request data partly built. The cleanup code that runs afterwards trusts that half-built data, and that trust is the opening (GHSA-w8hw-w9fx-j79w).

CVE-2026-109619 is a use-after-free. PHP keeps pointers to a request's internal state after freeing it, and the next request on the same worker can touch those pointers before they get reset (GHSA-6wmf-4rv5-p3rp).

Both paths were turned into working remote code execution. According to Help Net Security, one request is enough, and it fires before your application code runs. Qualys adds that researchers could also read PHP worker memory without logging in, which can hold session tokens, API keys and database passwords.

Who is affected?

Anything that serves web requests through PHP: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. PHP flags mod_php as the top priority. FPM's startup behavior happens to block one of the out-of-memory paths, but PHP has confirmed code execution against FPM through the session lifecycle under the right conditions, so FPM users shouldn't relax.

The long tail is old PHP. Before the release, Mallory counted roughly 884,000 internet-facing hosts whose banners report PHP 8.1 or older (The Hacker News). Those branches are out of support and get no regular patch.

Exploited before the fix

The disclosure didn't go to plan. PHP posted an advance notice on October 20. A post on social media leaked news of the release the same day, claiming a 10.0 score and every version since PHP 5. PHP has since rated both bugs 9.2 and has not confirmed the version claim.

On October 21, Patchstack logged active exploitation reports from hosting partners at 07:34 UTC, more than six hours before the patch. Cloudflare's CTO confirmed early attack traffic minutes later and pushed WAF rules to all customers.

Amazon's threat intelligence team then reported something stranger. Its MadPot honeypots caught a PHP2Shell exploitation attempt on October 17, four days before disclosure, from an IP belonging to a commercial anonymization service. Nobody has explained how that attacker had the details.

As of October 22, proof-of-concept repositories have started to show up on GitHub. Expect scanning to pick up.

How to fix it

Upgrade to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 from php.net. Distribution packages may backport the fix under an older version number, so the version string alone can mislead you. Check your vendor's advisory. PHP also published minimal source backports for 7.4, 8.0 and 8.1. Treat those as a bridge to a migration.

If you can't upgrade today, PHP's interim guidance includes:

  • For CVE-2026-109618: enforce memory_limit=-1 at the admin level, keep post_max_size small, and cap request size at the web server or proxy. This trades RCE risk for resource-exhaustion risk, so put container or cgroup limits in place.

  • For CVE-2026-109619: set session.upload_progress.enabled=0 in php.ini or the FPM pool, then restart workers. ini_set() and .user.ini won't do it.

None of this replaces the patch. The UK NCSC goes further: if a system can't be fixed now, take it offline.

After patching, confirm that the PHP serving traffic is the patched one. Containers, hosting panels and appliances often bundle their own build, and php -v in a shell may be reporting a different binary. Restart or redeploy workers, then put a finite memory_limit back.

Where hands-on practice fits

PHP2Shell is a memory-safety bug inside an interpreter. Your developers won't write one of those next sprint. The response skill still carries over, though: read an advisory, work out whether it reaches you, and judge how an attacker would chain it into a shell. Teams who have built an exploit chain by hand make that call in minutes. Teams who haven't tend to wait for someone else's blog post.

You can build that habit in the SimulationsLabs scenario library. In secureArchive, players review the source of a PHP upload service and turn a file-upload weakness into command injection. HealthChk starts from a dull health-check form and ends in a shell through insecure deserialization. Run them as an internal CTF or a cyber drill, and the analytics show who solved what and where people got stuck.

Start for free, with no credit card, and run your first PHP scenario this week.