
On October 21, 2026 (11:00 PM JST, 2:00 PM UTC), the PHP security team released fixes for two critical vulnerabilities that can lead to unauthenticated remote code execution (RCE) (PHP news). The pair is nicknamed “php2shell.” In Japan, a large number of organizations took services offline as a precaution while the release was only pre-announced (piyolog’s compilation).
This article is for engineers who run PHP. It is built around the official advisories (GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp) and separates what is confirmed from what is third-party claim or still unverified. Sources are given next to each statement. The situation is moving, so it is updated daily for the next two days. Times are in JST (UTC+9) unless noted.
| CVE-2026-109618 | CVE-2026-109619 | |
|---|---|---|
| Advisory | GHSA-w8hw-w9fx-j79w | GHSA-6wmf-4rv5-p3rp |
| Official title | RCE via OOM corruption | RCE via stale global state |
| Severity | CVSS v4.0 9.2 (Critical) | CVSS v4.0 9.2 (Critical) |
| Vector | AV:N / AC:H / AT:P / PR:N / UI:N | Same |
| Published | October 21, 2026 | October 21, 2026 |
Reading the vector: network attack, no privileges, no user interaction, but high attack complexity and a requirement that certain conditions be present. PHP says exploit portability and reliability depend on the PHP build, extensions, front-end behavior, and allocator layout. That is not “trivially exploitable,” but it has been shown to work against mod_php once the conditions line up (GHSA-w8hw-w9fx-j79w).
When PHP runs out of memory, it leaves the current execution context with longjmp() and aborts the request. In some contexts, however, this escape can happen before request memory is fully initialized. The request memory is then left in an inconsistent state, and the shutdown code reads it or branches on it (GHSA-w8hw-w9fx-j79w).
For triggering memory exhaustion, the advisory points to multipart parsing. A multipart request without a usable Content-Length can pass the initial post_max_size check. There is also no limit on how many headers one part can carry, and each header costs memory to represent inside PHP, so a request within post_max_size can still exhaust a normal memory_limit (GHSA-w8hw-w9fx-j79w).
By SAPI, according to GHSA-w8hw-w9fx-j79w:
| SAPI | What the advisory says |
|---|---|
| Apache mod_php | Calls shutdown unconditionally even if request startup failed. Happens before application code runs. RCE verified |
| PHP-FPM | Exits the child process if startup fails, which prevents exploiting the bad state. OOM can still be reached after a normal startup. A complete FPM exploit has not been demonstrated |
| FrankenPHP | Source analysis shows it also calls shutdown unconditionally, like mod_php. Not verified |
| LSAPI | Similar to FPM. An application-specific exploit seems likely, but is not verified |
The verified RCE targets mod_php in a normal prefork setup with multiple workers, using PHP’s default input and memory limits.
Per-worker global state (errors, sessions, objects, extension state) can fail to be reset at the end of a request and keep pointing at memory that has since been freed. If the next request handled by the same worker uses that stale state before normal initialization, it dereferences freed memory. The advisory lists the impact as unauthenticated heap use-after-free, memory disclosure, and RCE with the web worker’s privileges (GHSA-6wmf-4rv5-p3rp).
The paths GHSA-6wmf-4rv5-p3rp confirms:
fatal_error_backtraces path on PHP 8.5 when that setting is enabled (RCE confirmed on mod_php)session.upload_progress) path. The feature is on by default and does not require session_start() (verified on both mod_php and FPM)auto_detect_line_endings=1, the legacy assert.* settings in PHP 8.3 and later, or an invalid memory_limit) are emitted as diagnostics. Changing error_reporting or using @ does not prevent itThe trigger demonstrated so far is OOM during input processing.
According to GHSA-w8hw-w9fx-j79w, the fix removes longjmp() on OOM. Instead it uses a deferred, softer OOM that fires at the next safe point in the VM. If memory use reaches a second, higher threshold, it terminates immediately with _exit(). PHP’s normal memory-limit behavior is preserved.
The official advisories (GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp) list these as affected:
| Branch | Affected | Fixed in |
|---|---|---|
| 8.5 | before 8.5.12 | 8.5.12 |
| 8.4 | before 8.4.27 | 8.4.27 |
| 8.3 | before 8.3.36 | 8.3.36 |
| 8.2 | before 8.2.35 | 8.2.35 |
| 8.1, 8.0, 7.4 | Not in the official affected table. Minimal source backports are provided (PHP’s announcement) | Backport branches (below) |
| 7.3 and earlier | No fix from the PHP project | None |
There are also claims that the bug reaches back to 5.4.0. That comes from the reporting side (Calif), as relayed by Tenable, and has not been confirmed in the official advisory.
To check:
php -v # CLI version (may differ from the version serving the web)
php-fpm -v # PHP-FPM
apachectl -M | grep -i php # is mod_php loaded?
The CLI version and the PHP that serves web requests can be different things. Check the one that handles web traffic, including FPM pools and containers. With Docker, run docker run --rm <image> php -v against the image you actually use.
Distribution packages sometimes pick up the fix without changing the version number. In that case, check the changelog. Adjust package names to your environment.
# Debian / Ubuntu
apt changelog php8.4-cli | grep -i -m1 CVE-2026-109618
# RHEL / Rocky / Alma
rpm -q --changelog php | grep -i -m1 CVE-2026-109618
The vulnerable component is the PHP runtime itself. Updating WordPress or Laravel does nothing if PHP is not on a fixed version. Conversely, once PHP is updated, application-level fixes are not required for this issue.
There are reports (from Wiz and Calif, as relayed by Huntress and Tenable) of unauthenticated RCE demonstrated against WordPress, Drupal, and Joomla. Those are third-party reports that the official advisory does not confirm.
Where the main distributions stand as of the morning of October 22. Debian is from the Debian Security Tracker; the rest is from piyolog’s compilation. This is moving fast, so always check your own distribution’s advisory:
| Distribution | Status |
|---|---|
| Debian | trixie php8.4 fixed in 8.4.27-1~deb13u1 (DSA-6574-1); bookworm php8.2 fixed in 8.2.35-1~deb12u1 (DLA-4848-1). php8.4 in forky and sid is not yet fixed (Debian Security Tracker) |
| Ubuntu | USN-8948-1. 26.10, 26.04 LTS, 24.04 LTS and 22.04 LTS are fixed. 20.04 and 18.04 via Ubuntu Pro; 16.04 and 14.04 via Legacy Support |
| Arch Linux | Fixed in php 8.5.12-1 and php-legacy 8.3.36-1 |
| Gentoo | Fixed in GLSA 202610-02 |
| Alpine Linux | php85, php84 and php83 in edge are fixed |
| Amazon Linux | AL2023 php8.2 to 8.4 are fixed. php8.5 has only CVE-2026-109618 fixed (ALAS2023-2026-3304); the rest is pending |
| AlmaLinux, Rocky Linux, Oracle Linux | Fixed (including rollout in progress) |
| RHEL | RHSB-2026-013. Packages for RHEL 8, 9 and 10 are partly available, with the rest in progress |
| Remi repository | PHP’s announcement said there was no update as of October 21 and suggested switching to the distribution’s packages or building from source |
For Docker, the docker-library definitions (versions.json) are updated to the four fixed releases (8.5.12, 8.4.27, 8.3.36, 8.2.35). We have not verified that the images themselves have been published, so pull again and confirm with php -v. According to PHP’s announcement, Windows builds are listed on the official downloads page.
After updating, restart all PHP workers (FPM pools, Apache workers). Reloading configuration alone can leave old workers running.
These are the interim mitigations from PHP’s announcement and the two advisories (GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp). None of them makes you safe. Use them to buy time until you can update.
For CVE-2026-109618, set memory_limit to -1 in a way the application cannot override.
# Apache (mod_php)
php_admin_value memory_limit -1
; PHP-FPM pool configuration
php_admin_value[memory_limit] = -1
For CVE-2026-109619, disable session upload progress. Put it somewhere that is applied before request parsing: php.ini, the FPM pool, or the server configuration. ini_set() and .user.ini cannot be relied on. On PHP 8.5, also disable fatal_error_backtraces.
; php.ini
session.upload_progress.enabled = 0
fatal_error_backtraces = 0 ; PHP 8.5 only
; or in the PHP-FPM pool configuration
php_admin_flag[session.upload_progress.enabled] = off
After changing these, restart all workers. Also check that no finite memory limit has been put back at the pool, directory, or application level.
Three cautions:
memory_limit = -1 is not a complete mitigation. If an underlying allocation (such as mmap()) fails, the same path can still be reached. It also raises the risk that a single request eats all the server’s memory, so always combine it with the front-end limits belowRLIMIT_AS or RLIMIT_DATA limits (ulimit -v, systemd LimitAS= or LimitDATA=, and so on). PHP’s announcement says that when the limit is hit, mmap() fails and triggers the vulnerable pathPHP’s announcement lists these as measures that reduce risk but do not replace the fix:
post_max_size conservatively (around 8M if you don’t need file uploads, around 32M if you do; keep upload_max_filesize below it)Content-Lengthmax_input_nesting_level, and limit the number of input variables, multipart parts, headers per part, and uploadsCloudflare’s CTO announced WAF rules for known attack paths for all customers, including free plans. Cloudflare itself describes them as a stopgap, and they only apply to traffic that goes through Cloudflare (Tenable, piyolog’s compilation).
According to PHP’s announcement, for people building from source or without an LTS vendor, the PHP security team provides minimal backports for 7.4, 8.0 and 8.1 on these branches:
PHP-7.4-CVE-2026-109618-109619PHP-8.0-CVE-2026-109618-109619PHP-8.1-CVE-2026-109618-109619There is no fix from the PHP project for 7.3 and earlier. You need a vendor LTS (such as Ubuntu Pro) or a move to a supported version. Also note that PHP 8.2 reaches end of life on December 31, 2026, according to PHP’s announcement. This is a good moment to revisit your migration plan.
Updating does not remove a compromise that happened between disclosure and your patch. Huntress recommends watching for signs such as:
php-fpm, php-cgi, httpd, apache2) spawning shells (sh, bash, cmd.exe, powershell.exe), interpreters (python, perl), or download tools (curl, wget, nc, certutil.exe)/dev/tcp/, fsockopen, or mkfifowhoami, id, uname -a, or ipconfigHuntress lists indicators of compromise (IOCs) as “to be determined” for now. The PHP advisory recommends auditing with log_errors, error_log and error_reporting=E_ALL, while warning that an absence of log entries is not proof of safety.
This one is my own observation: a sudden rise in PHP-FPM log lines saying a worker “exited on signal 11 (SIGSEGV)” may indicate attempts. It is not an official IOC, but it is a useful lead.
If you suspect compromise, preserve logs and isolate the server. Every credential visible to the PHP worker (database passwords, API keys, tokens) will need to be rotated.
Reports on exploitation conflict. Here they are with a confidence level.
| Item | What is reported | Confidence |
|---|---|---|
| Attack attempts | watchTowr says its honeypot network observed attempts against both vulnerabilities (counts not disclosed). Cloudflare’s CTO posted that “early attacks” are emerging (piyolog’s compilation, Tenable) | Third-party report |
| Successful compromise | As of the morning of October 22, we found no public report of successful compromises or their scale. Huntress said that as of 4:30 PM US Eastern on October 21 it had not observed exploitation in partner environments | Not confirmed |
| Public bodies | CISA said it had observed no exploitation at the time of its notice, and as of the morning of October 22 the CVEs were not in the KEV catalog (Known Exploited Vulnerabilities). The Netherlands’ NCSC-NL also said public PoCs exist but active exploitation is unconfirmed (per piyolog’s compilation) | Primary sources not verified |
| Public PoCs | The PHP Foundation said it did not identify any functional exploits among the code that circulated after disclosure. Wiz, on the other hand, reported demonstrating unauthenticated RCE on WordPress, Drupal and Joomla (Tenable, Huntress) | Conflicting |
| Affected versions | The official table lists 8.2 to 8.5. “Back to 5.4.0” is Calif’s claim (Tenable) | Official and third-party differ |
| CVSS | Reported as 10.0 when the identifiers leaked, but the official rating is 9.2 (piyolog’s compilation, GHSA-w8hw-w9fx-j79w) | Official value is 9.2 |
Be careful with old information. Articles written right after the leak sometimes still say “no fix is available yet” or “5.x through 8.x are affected,” which no longer matches the official information.
Times are in JST. The source is piyolog’s compilation. The release of the fixed versions can also be confirmed in PHP news.
| When | What happened |
|---|---|
| 2024 | During an external audit (Quarkslab via OSTIF), the first signs of the OOM problem appear, but no attack path is found and agreement on a fix is hard to reach |
| July 30, 2026 | Calif starts auditing PHP |
| August 11 | Calif, and independently OpenAI, report an RCE with the same root cause |
| August 24 | Wiz reports an additional attack path |
| September 18 | OpenAI reports an additional attack path |
| October 21, around 12:00 AM | The two CVE IDs circulate with the wrong publication time and a wrong CVSS of 10.0 (technical details reportedly did not leak) |
| October 20 (UTC) | PHP pre-announces a critical security release for 2:00 PM UTC on October 21 (11:00 PM JST), a day earlier than originally planned |
| October 21, 3:26 AM | watchTowr posts that RCE details under embargo have leaked |
| October 21, 4:43 PM | Cloudflare’s CTO posts that WAF rules have been rolled out to all customers |
| October 21, 10:34 PM | The two GitHub advisories are published |
| October 21, 11:00 PM | The fixed releases (8.5.12, 8.4.27, 8.3.36, 8.2.35) are published |
| October 22, morning | Sakura Internet, Xserver and others complete server-side PHP updates (see below) |
After the pre-announcement, many organizations in Japan took services offline on the night of October 21 as a precaution. piyolog’s compilation (as of the morning of October 22) counts 211 organizations: government bodies, municipalities, financial institutions, games, e-commerce, video and streaming, shared-hosting providers, and more. Nikkei xTECH also reported the partial shutdown of Sakura Internet’s services and emergency maintenance at Cygames and pixiv.
According to piyolog’s compilation, shared-hosting providers that run PHP responded as follows (as of the morning of October 22; always check each provider’s notice):
On shared hosting, updating PHP is the provider’s job. But if you have selected an old PHP version, you may be outside the scope of the update. Check which PHP version your control panel uses.
Among public bodies in Japan, IPA and the National Cybersecurity Office urged preparation for the release on October 21 (piyolog’s compilation).
The daily updates will follow these points:
If you need help taking stock of your PHP environments, updating them, or checking for compromise, get in touch below.
