On 21 October 2026 the PHP project shipped emergency security releases for two critical flaws that the industry is calling PHP2Shell: CVE-2026-109618 and CVE-2026-109619. Both are remote code execution (RCE) bugs in PHP's own runtime, both are scored 9.2 (Critical) on CVSS v4.0, and both can be reached without logging in. If you run a website, a WordPress or Laravel app, a control panel or any other PHP service, this is a patch-today item.
This guide explains what PHP2Shell is, who is affected, how the bugs work at a high level, how to patch, what to do if you cannot patch yet, and how to check whether you were hit. It is written for defenders. It contains no exploit code and no weaponization steps.
Status note. This is a fast-moving incident and the facts below come from PHP's advisories and from security vendor write-ups published between 20 and 22 October 2026. Where sources disagree or something is unconfirmed, we say so. Check the PHP security advisories for the authoritative version.
PHP2Shell at a glance
| Item | Detail |
|---|---|
| Nickname | PHP2Shell (also written php2shell) |
| CVE IDs | CVE-2026-109618 and CVE-2026-109619 |
| Type | Remote code execution through memory corruption in PHP's runtime (CWE-824, access of uninitialized pointer, per Imperva) |
| Severity | CVSS v4.0 9.2 Critical for both (PHP's rating). NVD lists 9.8 under CVSS 3.1. watchTowr cited 10.0, which was not PHP's rating |
| Authentication | None required for the confirmed paths |
| Fixed in | PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35 (21 October 2026) |
| Not fixed upstream | 8.1 and older (end-of-life). Source backports exist for 7.4, 8.0 and 8.1 |
| Highest-risk setup | Apache with mod_php (prefork) |
| Complete fix | Update PHP, then restart all workers. Workarounds are partial |
What is the PHP2Shell vulnerability?
PHP2Shell is two bugs with one theme: PHP can be pushed into aborting a request in the middle of its own bookkeeping, and the cleanup that follows trusts memory that is not in a safe state.
- CVE-2026-109618, "RCE via OOM corruption". If PHP runs out of memory while a request is only partly initialized, shutdown code may later read or branch on that half-built data as if it were valid. Parsing a multipart request is one named trigger.
- CVE-2026-109619, "RCE via stale global state". Request-owned state can survive after the memory behind it was freed. A later request handled by the same worker can then use that stale pointer before it is reset. PHP confirmed paths through session upload progress and, on PHP 8.5, the fatal-error backtrace feature.
Imperva's analysis explains the common thread. PHP uses longjmp()-style "bailouts" to abandon a request on a fatal condition such as hitting memory_limit. If the bailout lands after PHP has published a pointer but before cleanup completes, stale or uninitialized state is left behind. In worker-based deployments such as Apache prefork or PHP-FPM, one process serves many requests, so state left by one request can affect the next.
The crucial point for defenders: the vulnerable code runs while PHP is parsing the request body, before your application code executes. Fully patched application code, a clean WordPress plugin list or a hardened framework does not protect you if the PHP runtime underneath is unpatched.
Who is affected?
Affected PHP versions
PHP's GitHub advisories list every release before 8.2.35, 8.3.36, 8.4.27 and 8.5.12 on those branches as affected. For older branches the picture is less clear:
- PHP's advisories do not state how far back the older, end-of-life branches are affected.
- Calif, Cloudflare and Sansec say PHP back to 5.4.0 is affected, CERT-EU and watchTowr say PHP 5 and later. PHP itself has not confirmed these ranges, and one summary notes not every historic release has been individually verified.
Treat any PHP 5.x, 7.x, 8.0 or 8.1 installation that serves web requests as affected unless your vendor says otherwise.
Affected deployment types
PHP says every installation serving web requests is at risk, including PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed. Risk is not equal:
- Apache mod_php (prefork) is rated highest. PHP confirmed exploitation of both flaws on it without the application doing anything special.
- PHP-FPM is the default on most modern distributions. PHP confirmed RCE through CVE-2026-109619 on FPM via the session path, and considers it susceptible to CVE-2026-109618 as well, although AlmaLinux notes no complete exploit has been shown for that one.
The exposure is large. Mallory counted about 884,000 internet-facing hosts whose banners reported PHP 8.1 or older. Banners are not proof of exposure, but it shows how many unpatchable long-tail systems exist. That includes appliances, control panels, old CMS installs and embedded devices.
Timeline
All dates are 2026 and come from the sources linked below.
| Date | Event |
|---|---|
| 11 Aug | Calif reports the first bug to PHP. A second follows on 21 Aug |
| 19-24 Aug | Wiz says it independently found the first flaw and reported to PHP on 24 Aug |
| 21 Sep | PHP acknowledges Wiz's reports and begins a coordinated fix |
| 17 Oct | Amazon Threat Intelligence records an exploitation attempt in its honeypot telemetry, four days before disclosure |
| 20 Oct | Details leak publicly. PHP issues an advance notice of an emergency release. CERT-EU publishes advisory 2026-018 |
| 21 Oct, 03:02 UTC | Cloudflare's initial WAF protections go live |
| 21 Oct, 13:34 UTC | GitHub advisories and fixed releases are published |
| 21 Oct | CISA and the UK NCSC publish alerts. watchTowr and Hadrian report exploitation attempts |
Because exploitation attempts predate disclosure, the review window for incident response should start on 17-20 October, not on the date you patched.
Is PHP2Shell exploited in the wild?
Yes, attempts have been reported, with caveats:
- Amazon Threat Intelligence reported an attempt on 17 October 2026 from a commercial anonymization service, and believes a threat actor was responsible. How they obtained exploit details is unknown.
- Cloudflare, watchTowr and Hadrian report attack traffic against customers or honeypots on 21 October. Hadrian said activity was mostly through the session upload progress path.
- PHP's own release text does not report exploitation. CISA said it had not observed exploitation at publication, and neither CVE was in the KEV catalog in the sources we reviewed. Huntress reported none on its partner systems at the time.
- Wiz said frontier AI models substantially lowered the barrier to building an exploit, and a public proof of concept exists. Sansec predicted mass exploitation within minutes of the patch.
No threat actor has been publicly attributed and no confirmed counts of compromised sites have been published. Treat reports of specific outages as unverified unless a vendor confirms them.
How to patch PHP2Shell
Patching is the only complete fix. PHP states that its workarounds close only some attack paths.
1. Update to a fixed release
Move to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or the equivalent package from your OS vendor.
- Debian, Ubuntu, RHEL, AlmaLinux and similar: use the distribution's update. Fixes are backported, so
php -vmay not change. Verify withrpm -q php-commonorapt list --installed 'php*'and compare with your vendor's advisory. AlmaLinux, for example, lists fixed builds for its 8, 9 and 10 streams and recommendssudo dnf clean metadata && sudo dnf upgrade 'php*'. - Third-party repositories, control panels and hosting stacks: these are not covered by distro fixes. Ask the vendor. Help Net Security reported the volunteer-run Remi repository had no update at publication, and advised using distribution packages or building from source in the meantime.
- Containers: rebuild images from a fixed base and redeploy, not just
apt upgradeinside a running container. - Windows and bundled PHP: look for
php.exeandphp-cgi.exeinside control panels, installers, CI runners and appliances.
2. Restart every PHP worker
Old long-lived workers stay vulnerable. Restart or replace PHP-FPM (master and pools), Apache when it loads mod_php, FrankenPHP, LiteSpeed PHP processes and containers. Confirm the master started after the update, for example by checking process start times.
3. Handle end-of-life PHP
PHP 8.1 and older receive no upstream releases. Your options, in order of preference:
- Upgrade the application to a supported branch (8.2 to 8.5). Support dates matter: 8.2 gets security fixes only until 31 December 2026, so plan to land on 8.4 or 8.5.
- Use a vendor backport, such as your distribution's LTS packages or commercial extended support, or build from PHP's published source backports for 7.4, 8.0 and 8.1.
- If neither is possible, take the system off the public internet. CISA says to take PHP-based systems offline if they cannot be updated, CERT-EU advises isolating internet-facing applications, and the UK NCSC says to consider it.
Temporary mitigations if you cannot patch yet
These are stopgaps from PHP's advisory and vendor guidance. None is a complete fix. Test them first, apply them where they take effect before request parsing (php.ini, conf.d, FPM pool config, or server config), not through ini_set() or .user.ini, and restart workers.
| Mitigation | Addresses | Notes |
|---|---|---|
session.upload_progress.enabled = 0 |
CVE-2026-109619 session paths | PHP suggests keeping it off after patching if unused |
session.use_strict_mode = 1 |
Session abuse | Recommended by TuxCare alongside the setting above |
fatal_error_backtraces = 0 |
CVE-2026-109619, PHP 8.5 only | Blocks only the confirmed backtrace path |
memory_limit = -1, set so apps cannot override it (for example php_admin_value) |
CVE-2026-109618 | Removes the runaway-script guard, so pair it with a container or cgroup memory limit. Avoid RLIMIT_AS and RLIMIT_DATA, which can trigger the vulnerable path |
Lower post_max_size and upload_max_filesize |
CVE-2026-109618 | Also limit request size at the web server or proxy |
| Block multipart/form-data at the edge | Both | Only if the app takes no uploads |
| Switch mod_php to PHP-FPM with the event MPM | Application-independent mod_php paths | Reduces exposure, does not remove it |
Purge session.save_path |
Poisoned session files | Do this after deploying session-related protections |
On the edge, Cloudflare enabled initial rules for all plans, and other WAF vendors including Imperva published virtual patches. Abstract Security's write-up suggests blocking multipart parts that carry a PHPSESSID field or serialized-object-style filenames, and blocking very long urlencoded field names, but notes the rules are based on public proofs of concept, should run in log mode first, and that size limits alone do not help because exploit bodies can be tiny. A WAF buys time. It does not replace the update.
How to detect PHP2Shell exploitation
No indicators of compromise had been confirmed in the sources we reviewed, and default web logs do not record POST bodies, so a clean log is not an all-clear. Behavioral signals that vendors recommend watching:
Request and error-log signals
- PHP fatal errors containing "tried to allocate" and "in Unknown on line 0", which indicate an allocation outside normal script execution.
- Bursts of very large POST requests to PHP endpoints from one source, followed by memory-limit errors or repeated HTTP 500 responses.
- Unusually large or malformed
PHPSESSIDvalues in requests or inSet-Cookieresponse headers. - Unexplained PHP worker crashes or churn, and Apache
AH00052child-exit entries following many large POSTs.
Process and host signals
- Web or PHP processes (
php-fpm,php-cgi,lsphp,httpd,apache2,nginxworkers) spawningshorbash, Python, Perl,curl,wget,ncorcertutil.exe. - Reconnaissance commands run as the web user, such as
whoami,idoruname -a, or command lines containing/dev/tcp/ormkfifo. - New files created by the web user in
/tmp,/dev/shm,/var/tmpor writable web directories. - Outbound connections from the web user to unfamiliar IPs, especially on non-standard ports.
Persistence checks
- Unfamiliar PHP files or web shells in the web root, recently modified application files.
- New cron entries for the web user, new or changed
authorized_keys, new local accounts. - New database users or unexpected record changes if the web user has database access.
If you think you were compromised
- Isolate the server from the network, but do not wipe it yet.
- Preserve web server logs, PHP logs, process listings and a disk or snapshot image.
- Patch and restart on a rebuilt or clean host. Patching stops future exploitation but does not remove access already gained.
- Rotate secrets that the PHP process could read: database passwords, API keys,
.envvalues, SMTP credentials, session secrets and signing keys. - Review the window from 17 October onward for the signals above, and check connected systems that share those credentials.
- Notify the right parties if personal data may have been exposed. In India, review your duties under the DPDP Act and our DPDP rules website compliance checklist.
Hardening so the next PHP bug hurts less
PHP2Shell lands in the runtime, so hardening cannot replace patching. It does limit the blast radius of this and future bugs:
- Least privilege. Run PHP as a low-privilege user with no write access to application code, and keep secrets out of reach where possible.
- Isolate sites. Give each site its own FPM pool and user, so one compromised site does not expose the rest of the server.
- Restrict egress. A web server rarely needs to open arbitrary outbound connections. Blocking them breaks many reverse shells and download stages.
- Disable what you do not use. Turn off upload progress, unused extensions and verbose error output on production.
- Keep an inventory. Know every PHP install you run, including appliances, CMS sites, staging servers and old microsites, and who patches each one.
- Monitor processes. Alert when a web worker spawns a shell. It is high-signal and cheap.
- Make updates routine. Treat runtime updates like application releases, with automated rebuilds and a maintenance plan that includes the server layer.
A well-run website maintenance routine, a technical SEO and site health checklist that includes uptime and security headers, and regular dependency reviews are what keep incidents like this from turning into downtime and lost search rankings. If you are unsure which PHP versions your sites run, or you want help with an emergency patch, contact our team or see our web development services.
Frequently asked questions
What is PHP2Shell?
PHP2Shell is the public nickname for two critical PHP runtime flaws, CVE-2026-109618 and CVE-2026-109619, that can allow unauthenticated remote code execution. They were disclosed together when PHP released fixes on 21 October 2026.
What is the difference between CVE-2026-109618 and CVE-2026-109619?
CVE-2026-109618 is caused by out-of-memory handling that leaves request data partly initialized, which cleanup code later trusts. CVE-2026-109619 is caused by request-owned state surviving after its memory is freed, which a later request on the same worker can use. They are different bugs with the same CVSS v4.0 score of 9.2.
Which PHP versions are fixed?
PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.1 and earlier are end-of-life and need a vendor backport, PHP's published source backports for 7.4, 8.0 and 8.1, or removal from the public internet.
Does PHP2Shell affect WordPress, Laravel and other PHP apps?
Yes, indirectly. The flaws are in the PHP runtime that runs those apps, so any PHP application served by an unpatched interpreter can be exposed regardless of its own code. Updating PHP, not the plugin or framework, is what fixes it.
Is PHP-FPM affected, or only mod_php?
Both. mod_php with Apache prefork is the highest-risk setup, but PHP confirmed a path through CVE-2026-109619 on PHP-FPM too, and also lists php-cgi, FrankenPHP and LiteSpeed as at risk.
Can I just disable session upload progress?
It helps with the confirmed session paths for CVE-2026-109619, and PHP suggests leaving it off if you do not use it. It does not cover CVE-2026-109618 or the PHP 8.5 backtrace path, so you still need to patch.
Is PHP2Shell on the CISA KEV list?
Not in the sources we reviewed as of 21 October 2026. Check the live CISA Known Exploited Vulnerabilities catalog, since that status can change quickly.
How do I check my PHP version safely?
Run php -v for the CLI, but remember that the web SAPI (FPM or Apache) may use a different binary. On distributions, query the package manager and compare against your vendor advisory because backports keep the old version string. Do not rely on external scanners alone, as they can false-positive on backported builds.
What should I do first today?
Inventory every PHP install, update to a fixed or vendor-backported build, restart all workers, review logs from 17 October onward, and rotate secrets if anything looks suspicious. Put unpatchable systems behind isolation or take them offline.
Sources
- PHP security announcement and release notes, 21 October 2026
- GitHub advisories: CVE-2026-109618, RCE via OOM corruption and CVE-2026-109619, RCE via stale global state
- Help Net Security: PHP2Shell, critical PHP vulnerabilities patched
- SecurityWeek: PHP2Shell, mass exploitation looms
- Imperva: PHP2Shell technical analysis
- watchTowr: PHP RCE FAQ
- AlmaLinux: patched PHP packages
- Brandefense: fixed PHP versions and timeline
- TuxCare: patch guide for end-of-life PHP
- Abstract Security: detection and WAF guidance
- Wikipedia: PHP2Shell
Last reviewed 22 October 2026. This article is general security information, not a guarantee of protection. Details may change as vendors publish more analysis.



