Skip to main content
14 speakers. 7 enterprise risk teams. One day in Charlotte, Oct. 22.Save My Seat
BlackKite: Home
Menu
blog

PHP2SHELL: Two Critical Remote Code Execution Vulnerabilities in the PHP Core

Published

Oct 21, 2026

Authors

Ferdi Gül

php2shell threat briefing: two critical PHP core RCE flaws

IN A NUTSHELL

On October 21, 2026, the PHP security team shipped an out-of-cycle emergency release and published its official advisory for two critical remote code execution (RCE) vulnerabilities in the PHP core. The flaws leaked on social media before the patch was available, and researchers nicknamed them "php2shell." Both are rated CVSS v4.0 9.2 (critical) and classified as CWE-416 (use-after-free). The advisory describes two distinct mechanisms: CVE-2026-109618 is a corruption that occurs during out-of-memory (OOM) handling, and CVE-2026-109619 is "stale global state" left behind in a worker. A working unauthenticated exploit was demonstrated against Apache mod_php with a default configuration.

1. EXECUTIVE SUMMARY

PHP quietly powers a large share of the web: content and e-commerce systems such as WordPress, Drupal, Joomla and Magento, shared-hosting platforms, control panels such as cPanel and Plesk, and countless enterprise applications that never advertise that they run PHP. When a vulnerability lands in the PHP core itself, it does not touch a single product — it can affect everything built on that foundation at once.

On October 20, 2026, the existence of two critical PHP RCE flaws leaked ahead of the coordinated disclosure date and before any patch was available. Within hours, independent researchers confirmed the flaws were real, and the PHP team moved the emergency release a day earlier, publishing it on October 21, 2026 at 14:00 UTC. The name is the researchers’ own and usually means one thing: an attacker sends a request to the server and, in return, gains the ability to run commands on it (a shell).

KEY FINDINGS

•    Two critical RCE flaws: CVE-2026-109618 (OOM corruption) and CVE-2026-109619 (stale global state). PHP rated both CVSS v4.0 9.2 (critical), CWE-416; the leak claimed CVSS 10.0.

•    mod_php is the highest risk: All PHP installations serving web requests are at risk — including Apache mod_php, php-cgi, PHP-FPM, FrankenPHP and LiteSpeed — and the official advisory rates mod_php the highest risk.

•    Demonstrated exploit: Unauthenticated full RCE was validated against mod_php with a default configuration (the session path also against FPM). No in-the-wild exploitation reported; not in the CISA KEV catalog.

•    Fixed versions: 8.2.35, 8.3.36, 8.4.27 and 8.5.12. The PHP team also published minimal source backports for the end-of-life (EOL) 7.4, 8.0 and 8.1 branches; there is no official fix for 7.3 and earlier, or 5.x.

•    Exposure (Black Kite / Shodan): ~1.90 million internet-facing PHP hosts (honeypots excluded). Of the ~1.37 million that disclose a version, 72.5% run EOL branches that no longer receive fixes.

2. HOW IT CAME TO LIGHT: AN EMBARGO LEAK

The most striking part of this incident is how it became public, as much as the vulnerability itself. A critical flaw is normally disclosed in coordination under an "embargo": the patch is prepared first, then the details are published. This time the order broke down.

On the morning of October 20, 2026, a user (petecooper) on Hacker News claimed that two critical PHP RCE flaws would be disclosed on October 22, that both carried CVSS 10.0, and that they affected versions going back to PHP 5. The post included both CVE identifiers, but the only evidence offered was "source: trust me, bro." The post was taken down, but screenshots were already circulating.

Shortly afterward, Kevin Beaumont (GossiTheDog) confirmed the leak, and watchTowr stated the flaws were real. PHP published its advance notice and moved the release a day earlier, to Wednesday 14:00 UTC. At the same hour, the patches and two detailed GHSA advisories were published.

Disclosure Timeline

Date / Time (UTC)

Event

Oct 20, morning

Anonymous post on Hacker News: two PHP RCE flaws, CVSS 10.0, PHP 5+ affected, to be disclosed October 22. The post is removed; screenshots spread.

Oct 20

Kevin Beaumont (GossiTheDog) confirms the leak. watchTowr confirms on X that the flaws are real.

Oct 20, 19:33

PHP publishes its official "Upcoming Critical PHP Security Release" advance notice.

Oct 21, 02:29

An archive tied to the leak is first uploaded to VirusTotal.

Oct 21, 14:00

The patches ship (8.2.35 / 8.3.36 / 8.4.27 / 8.5.12) and the official advisory plus two GHSA reports (OOM corruption, stale global state) are published.

Table 1. Timeline of the php2shell disclosure, from the initial leak to the official release.

3. CVE DETAILS

The official advisory describes the two CVEs as two distinct mechanisms. Both are fixed by the same releases (8.2.35 / 8.3.36 / 8.4.27 / 8.5.12) and classified as CWE-416 (use-after-free).

CVE

Official description

CVSS

Status

CVE-2026-109618

OOM corruption

OOM handling can interrupt PHP while internal request data is only partially initialized. Request cleanup may then treat the invalid data as valid. (GHSA-w8hw-w9fx-j79w)

9.2

Critical

Demonstrated exploit (mod_php)

In the wild: none

CVE-2026-109619

Stale global state

Request-owned internal state can survive after its backing memory has been freed. A later request on the same worker may use that stale state before normal initialization resets it. (GHSA-6wmf-4rv5-p3rp)

9.2

Critical

Demonstrated exploit (mod_php, FPM)

In the wild: none

Table 2. The two CVEs, their official root-cause descriptions, severity and exploitation status.

CVSS VECTOR AND INTERPRETATION

The CVSS v4.0 vector for both flaws is AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H: network-reachable, unauthenticated, no user interaction, with high confidentiality/integrity/availability impact. "Attack Complexity: High" and "Attack Requirements: Present" mean exploitation depends on build-specific conditions and heap layout, yet it is proven to work on a default configuration. The leak said CVSS 10.0; PHP’s official score is 9.2.

TECHNICAL DETAILS

IMPORTANT NOTE

This section is written for defense and awareness and contains no working exploit code or payloads. The explanation is a conceptual summary of the mechanism, based on PHP’s official GHSA advisories, and provides the technical context organizations need to make detection and mitigation decisions.

The official advisory defines two distinct mechanisms. Both can lead to unauthenticated RCE, are classified as CWE-416 (use-after-free), and are fixed by the same releases.

CVE-2026-109618 — RCE via OOM Corruption

PHP uses "longjmp()" to exit the current context and abort the request on out-of-memory (OOM) errors. In some contexts request memory is temporarily reachable before it is fully initialized. If any allocation fails at that point, PHP does not properly account for the early exit and leaves request memory in an invalid state. The failed allocation does not need to be related to the invalid memory. The request shutdown procedure may then read or branch on that invalid data — which can lead to remote code execution.

Trigger: an attacker can reliably force OOM with multipart requests that stay within apparent PHP limits. Examples include requests without a usable content length that pass the initial post_max_size check and keep supplying body data; a part containing an unrestricted number of headers (which take far more memory in PHP than on the wire, so a request within post_max_size can still exhaust memory_limit); and empty file controls that do not count toward max_file_uploads.

HIGHEST RISK: MOD_PHP

Apache mod_php unconditionally invokes the request shutdown procedure even when request startup has failed. Automatic body parsing during startup can exhaust the memory limit and exit the request in an invalid state, and shutdown then processes that invalid state — all before any application-specific code runs. Full RCE was validated against mod_php with default PHP input/memory limits. FPM exits the child when request startup fails, cutting this exact path (though source analysis still considers it susceptible). FrankenPHP is likely susceptible; LSAPI models FPM.

CVE-2026-109619 — RCE via Stale Global State

PHP holds various global state (error, session, object and extension state) that a worker retains but that points to memory owned by a single request. That state must be reset before the request memory is released. Some input, configuration, session and error-handling operations run before the next request’s normal initialization and inadvertently access stale, not-yet-reset state — a use-after-free. A carefully crafted heap layout can produce full RCE. Exploitation requires a "producer" (an operation that stores request-owned state where PHP can reach it later) and a "consumer" (a later operation that reads, frees or branches on that stale state); the two occur in different HTTP requests handled by the same worker.

There are two confirmed consumers. The first is INI diagnostics that run before request initialization: a warning or notice emitted by an invalid or deprecated INI setting can consume stale error state — it need not be fatal, displayed or logged, and error_reporting, "@" or display_errors do not protect against it. The second is session upload progress, which reaches session/decoder state before normal initialization. The strongest demonstrated case is fatal-error backtrace state on PHP 8.5 with "fatal_error_backtraces" enabled; this is the basis of the confirmed mod_php exploitation. The session upload progress lifecycle was validated against both mod_php and FPM. Note: session.upload_progress is enabled by default and requires no call to "session_start()."

5. AFFECTED VERSIONS AND SUPPORT STATUS

The official GHSA records list the affected versions for both flaws as "< 8.2.35, < 8.3.36, < 8.4.27 and < 8.5.12." Given the severity, the PHP security team also published minimal source backports for the end-of-life (EOL) 7.4, 8.0 and 8.1 branches. There is no official PHP fix for 7.3 and earlier, or for 5.x.

AFFECTED, FIXED AND BACKPORTED

•    Fixed (October 21 release): 8.2.35, 8.3.36, 8.4.27, 8.5.12.

•    PHP source backports (EOL, partial): minimal source backports for 7.4, 8.0 and 8.1 were published on GitHub; also check your distribution / LTS vendor.

•    No official fix: 7.3 and earlier, and 5.x branches — upgrade or take them off the internet.

Distributions (Ubuntu, Debian, RHEL, SUSE, Alpine, Amazon Linux, official Docker images) and LTS vendors received the patches in advance; to decide whether a host is patched, rely on your distribution’s security tracker rather than the upstream version number.

Branch

Fixed version

Status

Official patch?

8.5

8.5.12

Active support

Yes

8.4

8.4.27

Active support

Yes

8.3

8.3.36

Security fixes only

Yes

8.2

8.2.35

Security fixes only

Yes

8.1 / 8.0 / 7.4

source backport

EOL — PHP published minimal source backports

Partial

7.3 and down, 5.x

—

End of life — no official fix

No

Table 3. PHP branches, fixed versions and support status. Only 8.2–8.5 receive full official fixes; EOL 7.4/8.0/8.1 get minimal source backports.

6. EXPOSED SURFACE: THE SIZE OF INTERNET-FACING PHP

The figures below are drawn from VirusTotal’s internet-scanning data (October 21, 2026). These are fingerprint counts; they describe the size of the exposure window, not confirmed vulnerable systems.

Metric (VirusTotal, Oct 21, 2026)

Value

IP addresses fingerprinted as PHP

~5.1 million

PHP servers with at least one open port

~3.8 million

Servers disclosing a version in an HTTP header

~1.1 million (about 1 in 5)

Running a supported branch (8.2–8.5)

~272K

Running an EOL branch (5.4–8.1)

~758K

Table 4. Internet-facing PHP footprint. Only about one in five hosts discloses its version, so banner counts are a lower bound.

THE SINGLE MOST IMPORTANT FINDING
About four in five PHP servers hide their version ("expose_php = Off", stripped headers, reverse proxies). Hiding the version does not hide the vulnerability — so banner-based counts are a lower bound on the real exposure.

What Runs On Top

Web servers

Applications / high-value targets

Apache ~2.9M

WordPress ~538K

nginx ~1.48M

Laravel ~141K

LiteSpeed ~90K

Nextcloud ~107K

—

Roundcube + phpMyAdmin ~25K

Table 5. Web servers and applications most often seen on internet-facing PHP hosts (VirusTotal).


Because the official advisory rates mod_php the highest risk, Apache installations running mod_php should be scanned first. The geography is concentrated: ~920K of the PHP hosts with an open port are in the United States, and a handful of cloud/hosting providers (AWS, DigitalOcean, Alibaba, OVHcloud, Hetzner) hold a large share.

7. SHODAN STUDY: BLACK KITE EXPOSURE ANALYSIS

Black Kite measured the taggable exposure by scanning internet-facing PHP across the affected-era range (5.4.0 – 8.5.11) on Shodan, one version at a time. A total of 471 distinct versions were queried. Two baselines were used: all internet-facing PHP excluding honeypots (including hosts that hide their version), and hosts that disclose a version in their banner.

Query pattern used

http.component:"php" -tag:honeypot            -> 1,898,841 (baseline)
http.component:"php" "PHP/8.3.33" -tag:honeypot -> 29,758

METHODOLOGY NOTE: DE-OVERLAP CORRECTION

Shodan matches the version string as a substring: the query "PHP/5.4.1" also counts 5.4.10–5.4.19. Summing raw per-version counts therefore counts the same hosts repeatedly and inflates the total. Each query was de-overlapped by excluding the longer versions that start with it (e.g. "PHP/5.4.1" minus "PHP/5.4.10"…"PHP/5.4.19"). After the correction the numbers are consistent: the sum of the parts stays below the baseline.

HEADLINE FINDING
~1,898,841 internet-facing PHP hosts were found excluding honeypots (including version-hiding hosts). Of these, ~1,372,495 disclose a version in the affected range (5.4.0 – 8.5.11); the remaining ~526K hide their version. Of the version-disclosing hosts, 72.5% (~994K) run EOL branches that no longer receive security fixes — only 27.5% (~378K) are on supported 8.2–8.5 branches.
Figure 1. Share of version-disclosing internet-facing PHP by support status (de-overlapped Shodan data, Oct 21, 2026).

Figure 1. Share of version-disclosing internet-facing PHP by support status (de-overlapped Shodan data, Oct 21, 2026).

Distribution by Branch (de-overlapped)

Exposure concentrates in long-lived, slowly upgraded branches: PHP 7.4 (~223K), 5.4 (~201K) and 5.6 (~155K) lead. On the supported side the largest load is on PHP 8.2 (~175K) and 8.3 (~119K) — patchable, but requiring fast action.

Figure 2. Host distribution of version-disclosing internet-facing PHP by branch; red = EOL (no patch), green = supported.

Figure 2. Host distribution of version-disclosing internet-facing PHP by branch; red = EOL (no patch), green = supported.

Most Common Individual Versions

PHP version

Host count

Status

PHP/5.4.16

125,055

EOL

PHP/7.4.33

118,190

EOL

PHP/5.6.40

71,561

EOL

PHP/8.2.12

39,844

Supported

PHP/5.5.9

37,796

EOL

PHP/5.4.45

34,666

EOL

Table 6. The most common individual PHP versions after de-overlap correction (Shodan, Oct 21, 2026).

LINK TO FOCUSTAG TAGGING

These per-version counts are the raw basis for the FocusTag® tagging effort: each version is tagged against the affected range, honeypots are excluded, and the result is matched to the supplier ecosystem. This turns "there is a PHP vulnerability out there" into "these suppliers in my ecosystem are running that EOL version exposed to the internet," enabling prioritization.

8. PARTIES AFFECTED AND EXPOSED

As of this writing (October 21, 2026), no organization has reported a breach from these flaws and no in-the-wild exploitation has been confirmed; the flaws are not in the CISA KEV catalog. The official advisory does, however, confirm that a working unauthenticated exploit exists (mod_php; the session path also on FPM). "Affected parties" should therefore be read in two parts: the exposed platform classes and the vendors that responded.

Exposed Platform and Ecosystem Classes

  • Content management systems: WordPress (~538K internet-facing instances), Drupal, Joomla.
  • E-commerce: Magento / Adobe Commerce and similar PHP-based stores.
  • Frameworks and collaboration: Laravel (~141K), Nextcloud (~107K).
  • Admin panels: phpMyAdmin, Roundcube webmail, cPanel and Plesk.
  • SAPIs: Apache mod_php (highest risk), php-cgi, PHP-FPM, FrankenPHP, LiteSpeed/LSAPI.

Vendors That Responded

Party

Response

PHP security team

Out-of-cycle emergency release (8.2.35 / 8.3.36 / 8.4.27 / 8.5.12), two GHSA advisories, and source backports for 7.4/8.0/8.1.

Cloudflare

Shipped emergency rules to its Managed and Free WAF rulesets on October 21. CTO Dane Knecht stressed that only updating PHP fully protects a site.

watchTowr

Confirmed the flaws and said it reproduced one; identified exposure across its client base via Rapid Reaction / Active Defense.

Upwind

Published the first detailed independent assessment of the root cause.

Huntress

Published a rapid-response writeup; captured a baseline of PHP behavior and deployed detections.

Linux distributions

Ubuntu, Debian, Red Hat, SUSE, Alpine, Amazon Linux and Docker received the patches in advance / provide backport tracking.


Table 7. Vendor and researcher responses to php2shell as of October 21, 2026.

WARNING: RPMS.REMIREPO.NET

The PHP team noted that the volunteer-maintained rpms.remirepo.net repository will not have updates today. If you rely on it, switch to distribution packages or build from source so you can apply updates immediately.

9. DETECTION: WHAT EXPLOITATION LOOKS LIKE

Two detection layers should be used together: request level (the 5xx crash signal, loose multipart parsing and log audit from Section 4) and process level. At the process level, the trace left by this class of PHP RCE is consistent: a PHP worker process spawning an unusual child process.

A PHP worker (php-fpm, php-cgi, php-cgi.exe, httpd, apache2) launching any of the following warrants a closer look:

•    Shells: sh, bash, cmd.exe, powershell.exe

•    Interpreters / tools: python, perl, curl, wget, nc, certutil.exe

•    Reverse-shell patterns: /dev/tcp/, fsockopen, mkfifo

•    Recon commands: whoami, id, uname -a, ipconfig

In addition, the official advisory recommends a log audit: in an isolated audit with log_errors=On, a working error_log and error_reporting=E_ALL, review logs for repeated warnings/deprecations before target scripts run, diagnostics during extension/server cleanup, fatal/parse/uncaught errors, and "Maximum execution time exceeded." The absence of an error in the logs is not proof of safety.

10. MITIGATION AND PATCHING

UPDATING IS THE ONLY COMPLETE SOLUTION
The PHP security team states plainly that there is no complete generic configuration mitigation — an application, extension or server path may publish stale state or consume it without a predictable log entry. The measures below reduce exposure to specific attack paths but do not make an installation safe.

#

Action

1

Update to the fixed release: 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12. Patch internet-facing systems, and mod_php installations, first.

2

On EOL branches: PHP published minimal source backports for 7.4 / 8.0 / 8.1; check your distribution / LTS vendor. For 7.3 and earlier, or 5.x, upgrade or take the system off the internet.

3

If you rely on rpms.remirepo.net, there will be no update today; switch to distribution packages or build from source.

4

Monitor: treat 5xx as an attempt signal and suspicious child processes spawned by PHP as a possible success; audit logs. If you find something, isolate the server and preserve logs.

Table 8. Immediate response steps while planning the update.

Interim measures for CVE-2026-109618 (OOM)

; Enforced so applications cannot override (FPM pool / Apache):
php_admin_value[memory_limit] = -1
post_max_size = 8M       ; if no uploads (32M if uploads are needed)
upload_max_filesize < post_max_size
; Do NOT use RLIMIT_AS / RLIMIT_DATA -> triggers the vulnerable path
; A cgroup memory.max is only an availability bound, not a full fix

Interim measures for CVE-2026-109619 (stale state)

; php.ini / FPM pool / server (NOT ini_set or .user.ini), then restart workers:
session.upload_progress.enabled = 0
; PHP 8.5 — removes the confirmed RCE producer:
fatal_error_backtraces = 0
; optional — recycle the worker on every request:
pm.max_requests = 1

Also: eliminate attacker-reachable fatal errors and execution timeouts; remove invalid/deprecated INI diagnostics applied before request initialization.

Check your configuration

grep -rnE 'session\.upload_progress\.(enabled|name)' \
  /etc/php/ /etc/php.ini /etc/php.d/ /etc/php-fpm.d/ \
  /usr/local/etc/php/ 2>/dev/null

11. BLACK KITE PERSPECTIVE: PHP2SHELL IN THE SUPPLY CHAIN

The real story of php2shell is not a single server; it is scale. PHP is the invisible foundation of third-party ecosystems — even if an organization runs no PHP on its own assets, the web portals, customer panels and e-commerce infrastructure of its critical suppliers very likely run on it. This is a textbook case of cascading risk: a single core flaw travels downstream through third and fourth parties.

From a third-party cyber risk management (TPCRM) standpoint, the critical question is: "Which of my suppliers are affected by this vulnerability, and which should I reach first?" The Shodan data points to a clear priority here: 72.5% of the version-disclosing exposure sits on EOL branches that will get no patch; those suppliers are not a "just patch it" group but an "upgrade the branch or take it off the internet" group.

FocusTag®: Bridging a Global Threat to Your Ecosystem Risk

Black Kite®’s FocusTag® approach is designed precisely to close this gap: it takes a global threat (here, php2shell) and connects it to concrete, named risks in your own supplier ecosystem. A FocusTag® turns "there is a critical PHP vulnerability somewhere on the internet" into "these suppliers in your ecosystem run the affected version range, and here is how exploitable they are."

  • External, non-intrusive detection. Determine which suppliers run internet-facing PHP, and their exposure profile, from external signals without sending the supplier a single questionnaire.
  • Prioritization. Instead of "patch everything," "go to these suppliers first": those running EOL PHP, exposed to the internet and hosting high-value applications.
  • Nth-party visibility. See where the risk concentrates not only in your direct suppliers but in the sub-suppliers they depend on (your Nth-party ecosystem).

As the window from disclosure to first exploitation keeps shrinking — and in this case a working exploit is already proven — a defensible supply-chain posture is measured by speed and precision. The right question is not "are our servers patched?" but "is our entire cyber ecosystem patched?"

Black Kite's php2shell FocusTag® details critical insights on the event for TPRM professionals.

Black Kite's php2shell FocusTag® details critical insights on the event for TPRM professionals.

REFERENCES

https://www.php.net/archive/2026.php#2026-10-21-5

https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w

https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp

https://www.upwind.io/feed/initial-assessment-php2shell-two-critical-unpatched-php-rces-cve-2026-109618-cve-2026-109619

https://watchtowr.com/intelligence/php-cve-2026-109618-faq/

https://www.huntress.com/blog/php2shell-leaked-critical-php-vulnerabilities

https://sansec.io/research/php2shell

https://thehackernews.com/2026/10/php2shell-two-unpatched-critical-php.html

https://www.bleepingcomputer.com/news/security/php-warns-admins-of-two-critical-flaws-emergency-patches-coming-tomorrow/

https://blog.virustotal.com/2026/10/sizing-php-exposure-window-for-cve-2026.html

https://pentestit.com/php-cve-2026-109618-and-cve-2026-109619-what-we-know-about-php2shell/

https://cert.europa.eu/publications/security-advisories/2026-018/pdf