
PHP2Shell: Two Critical PHP Bugs Leaked Before the Patch, and Old PHP Will Never Get One
Details of two critical remote code execution flaws in PHP itself leaked a day before the fix. Attackers are already probing, the one-line workaround everyone shared does not hold, and close to 900,000 internet-facing servers run PHP versions that will never be patched. Here is what is known, what is still rumour, and what to do.
On this page
On 20 October 2026, the PHP security team announced an emergency release for two critical vulnerabilities in PHP itself: not a plugin, not a framework, the interpreter that runs WordPress, Drupal, Joomla, Magento and Laravel. Both are rated 9.2 on CVSS v4.0, and public reporting describes them as unauthenticated remote code execution.
That alone would make it a busy week. What makes this one dangerous is the order things happened in. The details leaked before the patch existed, exploit attempts started before the patch existed, and for a large part of the internet the patch is never going to exist.
This article reflects public information as of 21 October 2026, 18:30 IST (13:00 UTC), about an hour before PHP's scheduled release. Several technical claims are still unconfirmed, and they are marked as such.
At a glance
- CVEs: CVE-2026-109618 and CVE-2026-109619, nicknamed "PHP2Shell"
- Severity: CVSS v4.0 9.2 (Critical), per the PHP security team. Early leaked reports said 10.0; that figure is unverified.
- Impact: Unauthenticated remote code execution, according to CERT-EU's advisory 2026-018
- Affected: Not officially confirmed. CERT-EU and Australia's ACSC say PHP 5 and later may be affected.
- Fix: Scheduled for 21 October 2026, 14:00 UTC (19:30 IST), for the supported branches only: 8.2, 8.3, 8.4 and 8.5
- No fix, ever: PHP 8.1, 8.0, 7.x and 5.x, which are end of life
- Exploitation: Cloudflare's CTO says early attacks are emerging. Huntress, watchTowr and ACSC had not observed in-the-wild exploitation at the time of their posts.
- Workaround: None confirmed. A PHP core developer: "the only mitigation is patching / upgrading PHP."
How a planned patch became a race
Security fixes for widely used software are normally embargoed: the maintainers prepare a fix quietly, and the details go public at the same moment the fix does. Defenders and attackers start the race together. PHP2Shell broke that in a few hours.
From leak to patch in under 24 hours
- 20 October, around 15:20 UTC: An anonymous post on Hacker News claimed two critical PHP RCE bugs were about to be disclosed. It was deleted quickly, but screenshots spread. The original embargo reportedly ran to 22 October.
- 20 October, same day: PHP published an advance notice moving the release to 21 October, 14:00 UTC, and said it could release even earlier "should evidence of active exploitation appear in the wild." CERT-EU issued advisory 2026-018. watchTowr said it had reproduced one of the bugs. A researcher posted a short demonstration video, which was later taken down.
- 21 October, early: Write-ups attributed the bug to PHP's session upload-progress code, and a one-line configuration change spread across social media as the fix.
- 21 October, 05:00 UTC: GMO Flatt Security, the firm that first suggested that setting, said it is not a complete fix and that bypasses are expected.
- 21 October, 07:43 UTC: Cloudflare's CTO Dane Knecht said the company was "seeing early attacks emerging" and had deployed emergency WAF rules for all customers, free plans included.
- 21 October, 14:00 UTC: PHP's scheduled fix release.
Proof-of-concept repositories appeared on GitHub within hours. Some are verification tools, some claim full exploits, and at least one independent audit says the circulating exploit code does not work. That is normal for the first day of a leaked bug, and it will not last: once the patch is public, attackers can compare the fixed code with the old code and see exactly what changed. Sansec expects mass attacks to start within minutes of the release.
Why this one is so dangerous
It is in the interpreter, not an app
Most PHP security news is about a WordPress plugin or a framework. You patch the plugin, you are done. Here the bug is in the runtime underneath every PHP application on the server. According to W3Techs, PHP runs about 69% of websites whose server-side language is known. Updating WordPress, Laravel or your own code does nothing; the fix has to come from the PHP package, the container image, or your hosting provider.
No authentication, and a very common code path
Public analyses place at least one of the bugs in how PHP handles multipart form uploads, the format every file upload uses. PHP parses that request body before your application code runs. If that is right, it means:
- Your application's own checks cannot stop it. Login checks, CSRF tokens and upload validation all run after the vulnerable parsing has already happened.
- Turning off file uploads probably does not help either, because PHP still parses a multipart body when
file_uploadsis off. - Any page that accepts a POST could be the entry point, not just your upload form.
PHP has not confirmed the root cause, and some researchers dispute where exactly the bug lives. But the advice from every serious source is the same regardless: do not count on a configuration change.
The workaround that isn't
The fix that went viral overnight was session.upload_progress.enabled = 0. Here is where it stands:
- GMO Flatt Security, which suggested it, now says it is not a complete fix and expects bypasses.
- A researcher who analysed the leak says the second bug sits in the multipart parser and is reachable whatever this setting says.
- PHP 8.6 release manager Joe Ferguson: "ini settings won't save you."
- The setting is
PHP_INI_PERDIR, so it cannot be changed withini_set()at runtime, and a change in the wrong place (CLI config instead of the PHP-FPM pool,.user.iniunder mod_php) silently does nothing.
It costs almost nothing to disable (you only lose upload progress bars) so it is fine as one extra layer. Just do not mark the ticket as closed because of it.
What actually reduces risk before and after the patch
Old PHP gets no patch, at all
This is the part I think most people are underestimating. PHP only fixes branches it still supports, which today means 8.2 to 8.5. Everything older is end of life:
- PHP 8.1 reached end of life in December 2025.
- PHP 8.0 in November 2023.
- PHP 7.x and 5.x years before that.
If CERT-EU is right that the bugs go back to PHP 5, every one of those servers stays vulnerable after 19:30 IST today, with a public patch diff now showing attackers where to look.
Internet-facing PHP hosts by version: most get no fix
The numbers are rough but striking. A Shodan analysis by Mallory found about 1.5 million internet-facing hosts that advertise their PHP version. Of those, about 884,000 (59%) run a branch that will get no fix: around 369,000 on PHP 5.x, 329,000 on PHP 7.x and 186,000 on 8.0 or 8.1. Another 740,000 PHP hosts hide their version, so the real number is higher. Banner counts are not vulnerability counts, but the direction is clear.
For India, the same data shows about 53,600 PHP hosts, and of those that advertise a version, roughly 19,800 run a branch with no fix. Banner data cannot tell you whose servers these are, but PHP that old is usually the stuff nobody owns any more: legacy portals, small business sites, and shared hosting set up years ago and left alone.
Your options on an end-of-life branch, in rough order:
- Upgrade to a supported branch. Painful for old code, but it is the only clean answer.
- Get a backported fix from your Linux distribution or host, if they offer one. Enterprise distributions and some hosts patch old PHP packages on their own schedule. Check the CVE in their advisory, not the PHP version number.
- Take it off the internet: behind a VPN, an allowlist or authenticated access, and make sure nobody can reach the origin directly.
- Take it offline until one of the above is done. CERT-EU tells organisations that cannot patch to consider exactly that.
What to do now
Before the release
- Inventory every PHP runtime, not just your websites: PHP-FPM pools, Apache mod_php, CGI, containers, CI runners, control panels (cPanel, Plesk), Windows bundles like XAMPP, and appliances that ship PHP inside them.
- Mark which ones are internet-facing and which are on 8.1 or older. Those are your emergency list.
- Pre-stage the upgrade and agree who approves an emergency restart.
- If you are on Cloudflare, make sure the managed rules are set to block, not just log, and that the origin only accepts traffic from Cloudflare. A WAF in front of an origin that also answers directly protects nothing.
At and after the release
- Patch the supported branches immediately. Watch php.net and your distribution's advisory for the fixed versions. Pre-release reports name 8.5.12, 8.4.27, 8.3.36 and 8.2.35; confirm against the official announcement.
- Restart everything that runs PHP: PHP-FPM, Apache, Laravel Octane and queue workers. Long-running processes keep the old code in memory until they restart.
- Verify on the serving process, not with
php -vat the shell. The CLI and the web server often use different builds and configs. - Ask your host when a fixed PHP build lands, if you are on shared or managed hosting. Updating your app does not update their PHP.
Hunt, because the window was open
- Look for new or recently modified PHP files in web roots and upload directories. Webshells are the obvious end goal of a bug called PHP2Shell.
- Check for new admin users in your CMS, unexpected outbound connections from web servers, and crashing PHP workers: researchers note that failed exploit attempts often crash the worker, so a burst of 5xx errors on POST requests is worth a look.
- If a server was exposed on an end-of-life branch, assume compromise until you have checked, and rotate any credentials, API keys and cloud roles that live on it.
The takeaway
PHP2Shell is a reminder that "we'll patch it when the patch comes" only works if a patch is coming. For a supported PHP branch, today is a bad day with a clear fix at 19:30 IST. For the hundreds of thousands of servers still on PHP 5, 7 or 8.1, today is the day their technical debt became an open door, and no release note is going to close it.
If you run PHP anywhere, find out which branch it is today, not after the first webshell turns up.
This article reflects public information as of 21 October 2026, 18:30 IST. It will be updated with PHP's official advisory, affected and fixed versions, and any confirmed exploitation.
Sources
- The Hacker News: PHP2Shell, two unpatched critical PHP RCE flaws (CVSS 9.2) trigger emergency security alert
- The Hacker News: PHP2Shell, what actually protects you before the 14:00 UTC patch, and what doesn't
- Tenable: php2shell (CVE-2026-109618, CVE-2026-109619) FAQ
- Cyber Security News: Cloudflare detects early exploitation attempts targeting two leaked PHP vulnerabilities
- Cyber Security News: PHP2Shell vulnerability gets a public PoC exploit for security testing
- Mallory: PHP RCE in 8.5 and earlier, rapid response and exposure data
- Phoenix Security: PHP core RCE CVE-2026-109618 and 109619, patch and exposure
- Upwind: Initial assessment, PHP2Shell
- watchTowr: PHP remote code execution FAQ
- ma.ttias.be: PHP CVE-2026-109618 and CVE-2026-109619, early mitigation steps
- lilting.ch: Disabling session.upload_progress before the php2shell patch lands
- SecureLayer7: PHP RCE CVE-2026-109618 and 109619, what to do now
- Patchstack: Major security alert, PHP vulnerable to critical RCE
- BigGo Finance: EU authorities on taking unpatched sites offline (ACSC and CERT-EU guidance)
Related research
More vulnerabilities →

