On this page
Updated 26 October 2026. This is an updated version of the advisory we first published on 21 October 2026. Since then, exploitation attempts have been reported, including one four days before disclosure, exploit code has become public, the PHP project has disclosed a related session flaw (CVE-2026-115560), and the first indicators of compromise have been published. The exploitation status, mitigations, detection guidance and timeline below reflect those changes.
On 21 October 2026 the PHP project released PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 to fix two critical flaws in the PHP engine, tracked as CVE-2026-109618 and CVE-2026-109619 and widely nicknamed PHP2Shell. Both are rated 9.2 under CVSS v4.0. Both can be reached by an unauthenticated HTTP request. On Apache with mod_php, the PHP project has demonstrated remote code execution triggered before any application code runs, which means the application on top does not matter: a WordPress site, a Laravel API and a twenty-year-old in-house tool are exposed the same way.
The PHP project is unusually direct about the response. Its release notes say “there are no complete mitigations, updating is the only safe choice”, and its advisory adds that the configuration workarounds “do not make an installation safe”. Details leaked a day before the planned release, and AWS recorded the first exploitation attempt on 17 October, so the window between disclosure and attack never existed for this one.
What to do, in order
- Find every PHP runtime that answers on the internet. Start with Apache mod_php, then PHP-FPM, php-cgi, FrankenPHP and LiteSpeed. Include appliances and vendor products that embed PHP, and container images built on a PHP base.
- Update to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or to your distribution’s patched package, then restart every worker. An upgraded package with running workers leaves the vulnerable code in memory.
- If you cannot patch today, apply the configuration mitigations below, knowing that they close specific paths and not the vulnerabilities. If you cannot do that either, CISA and the UK NCSC both advise taking the system offline until it is fixed.
- Verify the version that each running server reports, not the PHP command-line binary, and check for compromise on every exposed host, reviewing logs from 17 October onwards.
The two vulnerabilities
| CVE-2026-109618 | CVE-2026-109619 | |
|---|---|---|
| PHP advisory | GHSA-w8hw-w9fx-j79w, “RCE via OOM corruption” | GHSA-6wmf-4rv5-p3rp, “RCE via stale global state” |
| Class | Memory corruption after an out-of-memory abort | Use-after-free across requests in the same worker |
| Trigger | Crafted request, typically multipart, that exhausts memory mid-initialization | A request that leaves stale state, then a later request on the same worker that uses it |
| RCE confirmed by PHP | Apache mod_php, over HTTP | mod_php and PHP-FPM via session upload progress; mod_php via PHP 8.5 fatal error backtraces and via start-up configuration warnings |
| CVSS v4.0 | 9.2 | 9.2 |
CVE-2026-109618, out-of-memory corruption. PHP handles running out of memory by jumping straight out of the current operation (longjmp()). In some places, request memory is already reachable before it is fully initialized. If an allocation fails at that moment, the half-built state stays behind, and request shutdown later reads or branches on it as if it were valid. The attacker’s task is to make PHP run out of memory at the right point, and the advisory lists several ways to do that while staying inside normal limits:
- A request body without a usable declared length can pass the initial
post_max_sizecheck. - A single multipart part can carry an unlimited number of headers.
- Empty file fields do not count toward
max_file_uploadsbut still create metadata arrays, and nested field names multiply the work.
CVE-2026-109619, stale state between requests. A persistent PHP worker keeps some global state (errors, sessions, objects, extension data) across requests, and some of it points into memory owned by a single request. That state has to be cleared before the request’s memory is freed. When a fatal error aborts an operation before its clean-up runs, the pointer survives, and the next request on the same worker can use freed memory before normal initialization resets it. Exploitation needs a “producer” request and a “consumer” request handled by the same worker. The advisory confirms three paths:
- Session upload progress, enabled by default: RCE validated against mod_php and PHP-FPM, where the FPM case needs an application operation the attacker can make fail.
- Fatal error backtraces, PHP 8.5 only, when
fatal_error_backtracesis on: RCE confirmed against mod_php. - Configuration warnings before the request starts, from
.htaccessor Apachephp_valuedirectives under mod_php. On FPM this depends on the front end passingPHP_VALUE.
The two compose: an out-of-memory error during multipart parsing, the core of the first flaw, is one of the confirmed ways to leave behind the stale session state the second one consumes.
A related flaw, CVE-2026-115560. On 23 October the PHP project published an informational advisory for a further remote code execution vector in session upload progress that the 21 October releases do not close. It needs an unusual setup: an application that sets session.serialize_handler to php_binary or php_serialize and switches it to php with ini_set() before calling session_start(). PHP will fix it in the next regular release and publish the full advisory then. Until that release, session.upload_progress.enabled = 0 fully protects against it, according to both PHP and Red Hat.
Who is exposed
The PHP project considers every installation serving web requests at risk. How directly depends on the server API (SAPI) that runs PHP:
| SAPI | What the PHP advisories confirm | Priority |
|---|---|---|
| Apache mod_php | RCE demonstrated over HTTP, unauthenticated, before any application code runs | Patch first |
| PHP-FPM | CVE-2026-109619 RCE validated through session upload progress, conditional on an application operation an attacker can make fail. CVE-2026-109618 susceptible by source analysis; no complete exploit shown | Patch now |
| php-cgi, FrankenPHP, LiteSpeed | Listed as at risk; FrankenPHP and LiteSpeed considered likely susceptible but not validated | Patch now |
| Command line only (cron, queue workers, build tools) | Outside the web request paths the advisories describe | Normal update cycle |
Versions. Every PHP release before the fixed versions is affected. PHP 8.1 and older no longer receive releases from the PHP project; its security team has published minimal source backports for the 7.4, 8.0 and 8.1 branches. Wiz and Cloudflare write that every version since PHP 5.4 is affected by at least one of the flaws. The PHP advisories do not confirm a lower bound, so treat any end-of-life PHP as vulnerable unless its vendor says otherwise. The UK NCSC also points out that appliances and services can bundle PHP and need their own vendor updates.
Distribution packages. Enterprise distributions backport fixes without changing the upstream version number, so a version string alone misleads in both directions: an old-looking 8.0.30 can be patched, and a current-looking build from a third-party repository may not be. Go by your vendor’s errata. AlmaLinux shipped patched packages for every PHP stream on AlmaLinux 8, 9 and 10 on the evening of 21 October, including retired streams, and notes that only AlmaLinux 8 ships mod_php. Red Hat’s bulletin RHSB-2026-013 lists RHEL 8, 9 and 10 as affected, and RHEL 7 by CVE-2026-109619 only; as of its 23 October update, some fixes were available and others still in progress. Red Hat rates CVE-2026-109618 Important (CVSS v3.1 8.1) rather than critical, because the default PHP-FPM setup on its platforms makes exploitation harder.
Exploitation status
As of 26 October 2026:
- Attempts began before disclosure. AWS recorded an exploitation attempt against its MadPot honeypots on 17 October, four days before the release, from a commercial anonymization network. More attempts followed between 02:00 and 08:00 UTC on 21 October, still under embargo, with payloads and infrastructure that point to several actors. AWS says it is unclear how the first actor obtained exploit information.
- Attempts continued after the release. watchTowr reports exploitation of both CVEs in the wild from 21 October. Cloudflare observed attack traffic against its customers and attackers mutating payloads to get past its rules. Sophos saw scanning and a small number of failed attempts that tried to drop a likely Mirai variant it calls Potassium.
- No confirmed compromise has been published. Sophos corrected an earlier report on 22 October and says it has “no evidence of a successful compromise due to these vulnerabilities”. CISA’s alert said it had not observed successful exploitation. AWS says it is unclear whether the attempts it saw would have worked on real systems.
- Still not on CISA’s list. The Known Exploited Vulnerabilities catalog, in its 23 October version, lists neither CVE. CISA’s alert still tells organizations that cannot update, or that run PHP 8.1 or older, to “take PHP-based systems offline until they can be patched or updated”.
- Exploit code is public, and not trivial to use. Sophos says proof-of-concept code is publicly available and that exploit development “is not straightforward”; success depends on deployment, PHP version and configuration. Red Hat notes that reliable exploitation requires precise heap manipulation and timing.
- Be careful with exploit code. Do not run proof-of-concept code from unknown sources on production or analyst machines; fake exploits are a common lure after a high-profile disclosure.
Our assessment: attackers had the bug before defenders had the patch. Treat every internet-facing PHP server that ran an unpatched build after 17 October as possibly targeted: update it as an emergency change, then check it for compromise. The absence from CISA’s catalog says that no successful compromise has been confirmed publicly. It does not say that attempts failed everywhere, and a failed attempt and a quiet success can look alike from the outside.
If you cannot patch today
Set these in php.ini, a php.d drop-in, the FPM pool or the server configuration (not with ini_set() or .user.ini, which the advisories say not to rely on), then restart every worker:
; CVE-2026-109619 and CVE-2026-115560: blocks the session upload progress path.
; Keep it off after patching, at least until PHP's next regular release.
session.upload_progress.enabled = 0
; CVE-2026-109619, PHP 8.5 only: blocks the fatal error backtrace path.
fatal_error_backtraces = 0
; CVE-2026-109618: removes PHP's own memory-limit failure. Enforce it so
; applications cannot set it back (php_admin_value in the FPM pool).
memory_limit = -1
; Keep request bodies small: 8M without uploads, 32M with them,
; with upload_max_filesize below post_max_size.
post_max_size = 8M
- Keep a memory ceiling outside PHP. With
memory_limit = -1, put a container or cgroup limit (memory.max) behind it, ideally with a policy that kills only the affected worker. Do not useRLIMIT_ASorRLIMIT_DATA(ulimit -v,ulimit -d) instead: they make allocations fail, which triggers the vulnerable path. An underlying allocation failure can still reach that path even with no PHP limit. - Recycle FPM workers. The CVE-2026-109619 advisory suggests
pm.max_requests = 1in the pool if performance allows, so that no stale state survives into the next request. - Filter at the edge. At the reverse proxy or WAF, cap the decoded request size, the number of input fields, multipart parts, headers per part and nesting depth, including chunked requests with no usable
Content-Length. If an application never accepts uploads, blockmultipart/form-datato it entirely. - Remove start-up warnings. Invalid or deprecated per-directory settings (
.htaccess,php_value,PHP_VALUE) that emit diagnostics at request start feed CVE-2026-109619. Hiding them witherror_reporting,display_errorsor@does not help; fix or remove them. - Fix reachable fatal errors. Attacker-triggerable fatal errors and execution timeouts, in upload and import handling, callbacks and clean-up code, are producer paths for the second flaw.
- On Enterprise Linux 8 with mod_php, AlmaLinux recommends moving back to the event MPM with PHP-FPM.
- Take the system offline if none of the above can be done quickly, as CISA and the UK NCSC advise.
WAF signatures help but have limits. Cloudflare has blocked PHP2Shell patterns on its free and paid plans since 03:02 UTC on 21 October, but it saw attackers mutating payloads, and its rule for CVE-2026-115560 does not cover sites that changed session.upload_progress.name. watchTowr goes further and describes .ini-based mitigations as ineffective. Mitigations and signatures buy time; they do not change the conclusion.
Detection and verification
Check the version that serves requests. php -v reports the command-line binary, which can differ from the one serving traffic. Check the FPM binary (php-fpm -v, or php-fpm8.3 -v on Debian-family systems), the package that provides Apache’s PHP module, or a temporary phpinfo() page behind authentication, removed afterwards. On distributions that backport, check the package release instead of the version number (rpm -q php-common on AlmaLinux and RHEL). Rebuild container images from a patched base image: a running container keeps the PHP it was built with.
Look from the outside. With PHP’s default expose_php = On, many servers announce their version in the X-Powered-By response header. That gives a fast first list, but it misses servers that hide the header and shows pre-backport version numbers, so it is a starting point, not a verdict. Set expose_php = Off once you are done.
Hunt. Start from 17 October, the earliest known attempt, not from the release date. The PHP advisory recommends auditing with log_errors on, an error_log set and error_reporting = E_ALL in the start-up configuration, and warns that clean logs do not prove a server is safe. CISA’s alert links a SIGMA rule for this activity. The UK NCSC advises checking any host you could not patch quickly for backdoors before you patch it. Look for:
Allowed memory size of … bytes exhaustedfatal errors reportedin Unknown on line 0, meaning they occurred while parsing the request, before any script ran, particularly from unauthenticated clients or on endpoints that take no uploads.- Worker crashes:
exit signal Segmentation fault (11)in the Apache error log, orexited on signal 11 (SIGSEGV)in the PHP-FPM log. Wiz adds bursts of HTTP 500 responses after multipart requests and unusually large or malformedPHPSESSIDcookies. - Multipart POST requests with unusually many part headers, many empty file fields or deeply nested field names, or carrying a
PHP_SESSION_UPLOAD_PROGRESSfield to endpoints that do not handle uploads. AWS singles out that field as the pattern to search for. - PHP or web server processes launching shells or downloading tools with
wgetorcurl, new files under the web root or in/tmp, unexpected cron jobs, and outbound connections from web workers.
Published indicators, defanged:
| Indicator | Type | Context | Source |
|---|---|---|---|
103.216.220[.]92 | IP | Attempt on 17 October, before disclosure | AWS |
31.223.184[.]166, 37.19.200[.]5, 134.209.159[.]64, 103.114.163[.]188, 95.217.98[.]37 | IP | Attempts on 21 October | AWS |
45.198.224[.]169 | IP | Source of exploit attempts | Sophos |
hxxp://92.118.112[.]100/nfs | URL | Payload download | Sophos |
134.199.154[.]64, 117.55.202[.]115 | IP | Potassium command and control | Sophos |
/tmp/nfs | File path | Dropped payload | Sophos |
php2shell-scan/109618 | User-Agent | Exploit traffic | Sophos |
B7kQpoc618 | String | Multipart boundary in exploit requests | Sophos |
0c5486f06620e26e316f4b33f318b0d646d5e1133789331aa2fed012360d1486 | SHA-256 | Likely Mirai variant | Sophos |
AWS warns that its addresses belong to shared anonymization infrastructure: use them to investigate, not as a block list.
Why the score alone will not rank this
Both CVEs carry the same score from the same vector (AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H). The vector already records that exploitation is complex and has preconditions. Other scorers disagree on that point: NVD rates CVE-2026-109618 9.8 under CVSS v3.1 with low attack complexity, Red Hat 8.1 with high complexity. What no vector can record is that the same flaw is application-independent code execution on a mod_php server and a conditional chain on an FPM pool, or that one of your PHP hosts is the customer portal and another a forgotten staging box. Ranked by CVSS, every PHP host lands in the same bucket. Ranked by what is internet-reachable, which SAPI runs it and what sits behind it, the order of work becomes obvious. Our CVSS vs EPSS page develops that argument in general.
Panop’s discovery starts from a company name, finds the services you expose and fingerprints what they run. For an advisory like this one, the first step above becomes a filter on an inventory you already have, not a search under time pressure. Request a scan to see where PHP answers on your perimeter.
Timeline
| Date | Event |
|---|---|
| 11 Aug 2026 | Calif first identifies the vulnerability class; Wiz and OpenAI find the flaws independently in the following weeks, according to TechTarget. Coordinated release planned for 22 October. |
| 17 Oct 2026 | AWS MadPot sensors record the first known exploitation attempt. |
| 20 Oct 2026 | Details and CVE IDs leak online. PHP brings the release forward to 21 October, 14:00 UTC; the advance notice is relayed on oss-security. |
| 21 Oct 2026 | Under embargo: first proof-of-concept exploits appear around 02:00 UTC (AWS); Cloudflare enables WAF rules at 03:02 UTC; Chainguard publishes patched images at 07:41 UTC. |
| 21 Oct 2026 | PHP publishes 8.5.12, 8.4.27, 8.3.36 and 8.2.35 with advisories GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp. CISA and the UK NCSC issue alerts. watchTowr reports exploitation of both CVEs in the wild. |
| 22 Oct 2026 | Sophos reports public proof-of-concept code and no evidence of a successful compromise. |
| 23 Oct 2026 | PHP publishes an informational advisory for CVE-2026-115560. CISA updates its alert with a SIGMA rule; Red Hat updates RHSB-2026-013. CISA’s Known Exploited Vulnerabilities catalog update lists neither CVE. |
| 26 Oct 2026 | Panop Research updates this advisory. |
This advisory reflects public information as of 26 October 2026. It was first published on 21 October 2026.
Sources
- PHP security advisory and releases, 21 October 2026 PHP
- Informational advisory: Session upload progress (CVE-2026-115560), 23 October 2026 PHP
- GHSA-w8hw-w9fx-j79w: RCE via OOM corruption (CVE-2026-109618) PHP
- GHSA-6wmf-4rv5-p3rp: RCE via stale global state (CVE-2026-109619) PHP
- Upcoming Critical PHP Security Release (advance notice), 20 October 2026 oss-security
- Critical Vulnerabilities in PHP Require Immediate Patching (updated 23 October 2026) CISA
- Known Exploited Vulnerabilities catalog CISA
- Critical security issue affecting PHP NCSC (UK)
- RHSB-2026-013: Request handling memory corruption in PHP (updated 23 October 2026) Red Hat
- CVE-2026-109618 Red Hat
- CVE-2026-109618 NVD
- php2shell (CVE-2026-109618, CVE-2026-109619): Patches in progress AlmaLinux
- Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot AWS
- PHP Remote Code Execution ("PHP2Shell" CVE-2026-109618 & CVE-2026-109619) watchTowr
- Proof-of-concept exploit released for PHP vulnerabilities (CVE-2026-109618, CVE-2026-109619) Sophos
- Cloudflare deploys protections against php2shell vulnerability Cloudflare
- PHP2Shell: AI uncovers critical RCE vulnerabilities affecting 70% of the Internet Wiz
- PHP2Shell disclosure unravels after leaks forced early patch drop, 22 October 2026 TechTarget