On this page
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: updating is the only complete fix, and the configuration workarounds it publishes “reduce exposure to specific attack paths but do not make an installation safe”.
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.
- Verify the version that each running server reports, not the PHP command-line binary, and review logs from 20 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-initialisation | 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 |
| 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 initialised. 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 towards
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 initialisation resets it. PHP confirmed two paths: session upload progress, which is enabled by default, and on PHP 8.5, fatal error backtraces. Exploitation needs a “producer” request and a “consumer” request to be handled by the same worker.
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.
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, and Linux distributions and long-term-support vendors received the patches in advance. Some third-party write-ups claim that every version since PHP 5 is affected. The PHP advisories do not confirm a lower bound, so treat any end-of-life PHP as vulnerable unless its vendor says otherwise.
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. On release day, AlmaLinux was still building packages, and the PHP project warned that the Remi repository would not have updates the same day. 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; AlmaLinux notes that its versions 9 and 10 do not ship mod_php at all.
Exploitation status
As of 21 October 2026:
- An exploit has been demonstrated. The PHP project demonstrated unauthenticated remote code execution against Apache with mod_php. Red Hat notes that reliable exploitation requires precise heap manipulation and timing.
- Not yet on CISA’s list. CISA’s Known Exploited Vulnerabilities catalog did not list either CVE in its 21 October update. That means no confirmed exploitation had been published, not that no one is trying.
- 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: with the fixes public, an exploit already demonstrated by the PHP project and the number of PHP servers on the internet, treat internet-facing PHP as a target and run the update as an emergency change, not as part of the next maintenance window.
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: blocks the confirmed session upload progress path.
; Keep it off after patching if no application uses upload progress.
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
For PHP-FPM, the same in the pool configuration, plus an optional setting that breaks the same-worker requirement of CVE-2026-109619 at a real cost in throughput:
php_admin_value[memory_limit] = -1
php_admin_flag[session.upload_progress.enabled] = off
pm.max_requests = 1
Know what each of these does not do:
memory_limit = -1removes a safety net. Put a container or cgroup memory 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.- 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.
If your WAF or intrusion prevention vendor has shipped signatures for these CVEs, they 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. 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. The PHP project had not published indicators of compromise at the time of writing; the signals below follow from how the flaws work. The PHP advisory recommends auditing with log_errors on, an error_log set and error_reporting = E_ALL in the start-up configuration. Review from 20 October onwards:
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. - 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. - After any crash: unexpected child processes of the web server user, new files under the web root, and outbound connections from web workers.
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. What it cannot 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 |
|---|---|
| 20 Oct 2026 | PHP announces a critical security release for 21 October, 14:00 UTC; the advance notice is relayed on oss-security. Distributions and long-term-support vendors receive the patches in advance. |
| 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. |
| 21 Oct 2026 | CISA’s Known Exploited Vulnerabilities catalog update does not list either CVE. |
This advisory reflects public information as of 21 October 2026.
Sources
- PHP security advisory and releases, 21 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
- CVE-2026-109618 Red Hat
- php2shell (CVE-2026-109618, CVE-2026-109619): Patches in progress AlmaLinux
- Known Exploited Vulnerabilities catalog CISA