PHP Ships Emergency Patches for Critical PHP2Shell RCE Flaws
PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35 fix two critical, unauthenticated RCE flaws rated CVSS 9.2 that hit almost every PHP web server. Patching is the only real fix.
On October 21, 2026, at 14:00 UTC, the PHP project shipped emergency security releases—PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35—to fix two critical memory-safety bugs the security community has nicknamed "PHP2Shell." Both CVE-2026-109618 and CVE-2026-109619 allow unauthenticated remote code execution and are each rated 9.2 (Critical) under CVSS v4.0. They affect essentially any PHP installation that serves web requests—PHP-FPM, Apache's mod_php, php-cgi, FrankenPHP, and LiteSpeed—which in practice means a large share of the web, including WordPress and Drupal sites and countless custom applications. If you run PHP on a server that talks to the internet, the short version is: update to the patched point release for your branch today, restart every PHP worker and long-running PHP process afterward, and do not treat configuration tweaks as a substitute for patching.
- CVE-2026-109618 — GHSA-w8hw-w9fx-j79w: RCE via out-of-memory (OOM) handling corrupting partially-initialized request data. CVSS v4.0: 9.2 (Critical).
- CVE-2026-109619 — GHSA-6wmf-4rv5-p3rp: RCE via stale global state (a heap use-after-free) reused by the next request handled by the same worker. CVSS v4.0: 9.2 (Critical).
- Patched versions: PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35.
- Patch date: October 21, 2026, 14:00 UTC.
- Unsupported branches: PHP 8.1 and older are end of life; the PHP security team published minimal source-level backports for 7.4, 8.0, and 8.1 for people building from source.
What PHP2Shell actually is — two bugs, not one
"PHP2Shell" is shorthand the security community has attached to a pair of related but distinct vulnerabilities that the PHP security team disclosed and patched together. Both live in PHP's core request-handling machinery rather than in any specific extension, framework, or application code, which is why they are so broadly exploitable. Per the official GitHub Security Advisory for the pair, the PHP project rates both at a CVSS v4.0 base score of 9.2, and both are tracked under CWE-416 (use-after-free), CWE-755 (improper handling of exceptional conditions), CWE-824 (access of uninitialized pointer), and CWE-1325/CWE-1419 (improperly controlled sequential memory allocation / state issues). The two advisories explicitly cross-reference each other, and the PHP security team's own remediation guidance treats them as a matched set that needs the same fix: update the runtime.
CVE-2026-109618: RCE via out-of-memory corruption
According to the NVD entry for CVE-2026-109618, PHP historically used longjmp() to abort request handling when it hit an out-of-memory (OOM) condition. The problem is that some internal contexts weren't written to expect that abrupt exit: they can leave request memory in an uninitialized state right before an allocation that then never completes. PHP's own shutdown and cleanup routines can subsequently read or branch on that invalid memory, which the GitHub advisory says can be triggered consistently through several different OOM strategies and used for remote code execution. The advisory specifically calls out PHP's multipart form-parsing path—missing content-length handling, unlimited parts per request, and empty file fields with deeply nested names—as a reliable way to force a worker into this state.
The fix, described in the advisory and reflected in the official PHP ChangeLog under the entry "Avoid state corruption via bailout," removes the abrupt longjmp()-on-OOM behavior. Patched PHP now holds the OOM condition and raises it at the next safe point in the Zend virtual machine once the configured memory_limit is crossed, with a second, higher hard limit that kills the worker process outright via _exit() rather than letting it run cleanup on corrupted state.
CVE-2026-109619: RCE via stale global state (a heap use-after-free)
The second bug, tracked as CVE-2026-109619, is a more classic heap use-after-free. PHP keeps various pieces of global state inside a worker—error state, session state, object state, and extension state—that can temporarily point into memory owned by the current request. In some code paths that global state isn't correctly reset, or gets repopulated after being reset, before the request's memory heap is freed. The next request handled by that same worker can then read or branch on a pointer into memory that no longer belongs to it, before PHP's normal initialization has had a chance to reset things. The advisory identifies two confirmed ways to trigger this: PHP's early INI diagnostics (reachable via .htaccess or directory configuration under mod_php) and the session upload-progress feature. It also notes that fatal errors, including OOM and execution-timeout conditions, can skip the state reset that would otherwise prevent this—and that the fully confirmed remote-code-execution path requires PHP 8.5 with fatal_error_backtraces enabled, while the session upload-progress path was validated against both mod_php and PHP-FPM.
Who is exposed: PHP-FPM, mod_php, php-cgi, FrankenPHP, LiteSpeed
Both advisories and PHP's own security advisory posted to php.net describe the exposure the same way: any PHP installation that serves web requests is potentially affected, regardless of which SAPI (server API) sits in front of it. That list explicitly includes PHP-FPM, Apache's mod_php, php-cgi, FrankenPHP, and LiteSpeed. PHP's own advisory singles out mod_php as the highest-risk configuration, stating there is "a demonstrated exploit where an unauthenticated request can trigger the attack before any application code runs." That phrasing matters: this isn't a bug in WordPress, Drupal, Laravel, or any particular CMS or framework—it sits underneath all of them, in the PHP runtime itself, so patching your application code or plugins does nothing to close it. Running multiple FPM workers reduces the odds that any single request lands on a worker in the vulnerable state, but PHP's team is explicit that this only lowers the per-request success rate; it does not remove the vulnerability.
Affected versions vs. patched releases
Both CVEs affect the same four actively maintained PHP branches, each below the version it was patched in, according to the PHP ChangeLog and the NVD records for both CVEs:
| Branch | Affected versions | Patched in | Branch support status |
|---|---|---|---|
| PHP 8.2 | < 8.2.35 | 8.2.35 | Security-only; branch EOL 31 Dec 2026 |
| PHP 8.3 | < 8.3.36 | 8.3.36 | Security-only until 31 Dec 2027 |
| PHP 8.4 | < 8.4.27 | 8.4.27 | Active support until 31 Dec 2026 |
| PHP 8.5 | < 8.5.12 | 8.5.12 | Active support until 31 Dec 2027 |
| PHP 8.1 and older | All versions | No official release — minimal source backports only | End of life (8.1 since 31 Dec 2025) |
PHP 8.6.0 RC4, also published on October 21, already includes both fixes; anyone testing earlier 8.6.0 pre-release builds should move to RC4 or later.
Is PHP2Shell being exploited right now?
This is the part of the story where Pandromeda has to be careful about what's actually confirmed versus what's circulating in the security community. Multiple security vendors and researchers reported observing attack traffic attempting to exploit the two flaws within hours of the public disclosure, and several outlets have cited Cloudflare as one of the vendors making that claim. Pandromeda was not able to independently verify a primary Cloudflare write-up making that specific claim, so we are attributing it to those secondary reports rather than presenting it as something we confirmed ourselves. What is independently verifiable is narrower: PHP's own advisory describes a "demonstrated exploit" against mod_php used during the security team's own analysis, and the GitHub advisory for CVE-2026-109619 says the full RCE chain was validated by the researchers who reported it, on PHP 8.5 and against mod_php/FPM. Whether or not opportunistic scanning has started against the open internet at scale, the underlying math doesn't change: both bugs are pre-authentication, both reach code execution, and the patched fix is already public, which historically narrows the window for defenders fast once attackers start reverse-engineering the diff.
Why "disable session.upload_progress" is not a fix
A specific mitigation has circulated widely since the disclosure: set session.upload_progress.enabled=0 in php.ini or your FPM pool configuration and restart your workers. That advice is accurate, but it is incomplete in two important ways. First, per the GHSA-6wmf-4rv5-p3rp advisory, it addresses only one of the two confirmed trigger paths for CVE-2026-109619—it does nothing for the early-INI-diagnostics path under mod_php, and it does nothing at all for the separate out-of-memory bug tracked as CVE-2026-109618. Second, PHP's own guidance is unambiguous that none of the configuration-level mitigations "make an installation safe," and that updating to a patched release is the only complete fix for either vulnerability. If you can't update immediately, the fuller set of partial mitigations PHP's security team listed includes setting memory_limit=-1 via php_admin_value where FPM allows it, capping post_max_size (around 8–32MB depending on whether uploads are needed) with upload_max_filesize kept below it, avoiding RLIMIT_AS/RLIMIT_DATA, and—on PHP 8.5 specifically—also setting fatal_error_backtraces=0. Every one of those is a stopgap, not a cure, and every one requires a full worker restart to take effect, the same as the real patch does.
Running PHP 8.1 or older? Here's what actually exists for you
If your stack is still on PHP 8.1, 8.0, 7.4, or earlier, there is no official patched release coming: PHP's own supported-versions page confirms PHP 8.1 reached end of life on December 31, 2025, with 8.0 and 7.4 having gone end of life years earlier. That said, given the severity, the PHP security team made an exception and published minimal source-level backport branches for PHP 7.4, PHP 8.0, and PHP 8.1 directly in the php-src repository, intended for people building PHP from source or without access to a commercial long-term-support vendor; this is explicitly not a full, tested release, and php.net's own guidance is to check with your Linux distribution or LTS vendor for a packaged fix, or to upgrade to a currently supported branch (8.2 or later) rather than rely on the raw backport. PHP 8.2 itself is worth flagging here too: it is already in security-only support and reaches its own end of life on December 31, 2026, so sites patching to 8.2.35 right now should already be planning their next upgrade.
What to do right now
For anyone operating a PHP-based site or service, the action list is short and should be treated as urgent rather than routine patch-cycle maintenance:
- Identify every PHP version you run—web app servers, cron workers, queue workers, CLI scripts, CMS admin panels, and any container images or golden AMIs that bundle PHP.
- Update to the patched point release for your branch: 8.5.12, 8.4.27, 8.3.36, or 8.2.35. If you're on a managed host or Linux distribution, confirm your vendor has shipped the equivalent backported package rather than assuming it happened automatically.
- Restart every PHP-FPM pool, mod_php-enabled Apache process, and any other long-running PHP worker or service after updating. A package upgrade alone does not clear out already-running processes still executing the old, vulnerable code.
- If you cannot update immediately, apply the partial mitigations above as a stopgap—disabling
session.upload_progress, cappingpost_max_size/upload_max_filesize, settingmemory_limit=-1via admin value, and (on 8.5) disablingfatal_error_backtraces—and restart workers immediately after changing any of them, sinceini_set()and.user.inichanges are explicitly called out as insufficient. - If you're stuck on PHP 8.1, 8.0, or 7.4, check with your distribution or LTS vendor for a backported package before resorting to the raw source backport branches, and put a real upgrade plan on the calendar—these branches have no further official support coming.
- Audit your supply chain, not just your own code: shared hosts, managed WordPress/Drupal platforms, and any third-party PHP services you depend on should be able to tell you their patch status on request.
None of this is optional cleanup. Both flaws are unauthenticated, both reach remote code execution, and the PHP project itself is the one saying that only the runtime update closes the hole—much like other recent incidents where the only durable fix lived upstream rather than in any one application's own code, as Pandromeda covered in its look at how registries are trying to block malicious installs further down the supply chain. And if you suspect a box was already compromised before you could patch, treat it the way you'd treat any other confirmed intrusion—rotate credentials, check for unexpected admin accounts and scheduled tasks, and follow the same breach-response basics Pandromeda outlined after the Loblaw breach, rather than assuming a clean restart is enough.
Frequently asked questions
What is PHP2Shell?
PHP2Shell is the nickname for a pair of critical PHP core vulnerabilities, CVE-2026-109618 and CVE-2026-109619, disclosed and patched by the PHP project on October 21, 2026. Both allow unauthenticated remote code execution and are rated 9.2 (Critical) on the CVSS v4.0 scale.
Which PHP versions are affected and which are patched?
Every PHP release below 8.2.35, 8.3.36, 8.4.27, or 8.5.12 is affected, depending on branch. Updating to the matching patched version (8.5.12, 8.4.27, 8.3.36, or 8.2.35) is the only complete fix according to PHP's own advisories.
Is setting session.upload_progress.enabled=0 enough to be safe?
No. That setting only addresses one confirmed trigger path for CVE-2026-109619 and does nothing for CVE-2026-109618 or the other trigger path PHP's advisory describes. PHP's own guidance says configuration changes do not make an installation safe; only updating does.
Do I need to restart my server after patching?
Yes. Updating the PHP package alone does not affect processes that are already running. Every long-running PHP-FPM pool, mod_php-enabled Apache worker, or other persistent PHP service needs a restart to actually load the fixed code.
What if I'm still running PHP 8.1 or older?
PHP 8.1 and earlier are end of life and get no official PHP release for these CVEs. The PHP security team published minimal source-level backport branches for 7.4, 8.0, and 8.1 on GitHub for people building from source, but php.net recommends checking with your distribution or LTS vendor, or upgrading to a supported branch.
Has PHP2Shell actually been exploited in the wild?
Several security vendors and researchers reported seeing attack traffic against the flaws within hours of disclosure, though Pandromeda could not independently verify a primary vendor write-up making that claim. PHP's own advisory separately describes a demonstrated working exploit used during its own analysis against mod_php.
Sources
Sana Qureshi runs the security and privacy desk. She reports on actively exploited vulnerabilities, vendor patches and data breaches, and covers the password managers, VPNs and authentication tools readers use to protect themselves. Her alerts cite vendor advisories, CISA and the CVE record directly.

