Automated Threat Modeling

PHP CVE-2026-109618 and CVE-2026-109619: Unauthenticated RCE in the PHP Runtime

CVE-2026-109618 and CVE-2026-109619 let unauthenticated attackers run code on PHP web servers. PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix both. Technical analysis, affected setups, detection and mitigations for teams that cannot patch today.

CVE Analysis

8 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-10-21

PHP CVE-2026-109618 and CVE-2026-109619: Unauthenticated RCE in the PHP Runtime
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

On October 21, 2026 the PHP project released PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 to fix two critical vulnerabilities in the PHP runtime itself. CVE-2026-109618 and CVE-2026-109619 both allow unauthenticated remote code execution as the web worker user, and both are rated CVSS 4.0 9.2. Against Apache with mod_php, a working exploit fires before any application code runs, so the framework and the application on top offer no protection.

The PHP security team announced the release a day in advance, on October 20. Linux distributions and LTS vendors received the patches before publication.

CVEAdvisoryVulnerability
CVE-2026-109618GHSA-w8hw-w9fx-j79wOut of memory handling leaves request data half built, and request cleanup can use it
CVE-2026-109619GHSA-6wmf-4rv5-p3rpState from one request outlives it, and a later request on the same worker can use the freed memory

Technical Information

CVSS Breakdown

Both vulnerabilities share the same vector:

CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
  • Attack Vector: Network. The attack arrives as ordinary HTTP requests.
  • Attack Complexity: High and Attack Requirements: Present. Success depends on how the server is set up. For CVE-2026-109618, the advisory names the PHP build, the loaded extensions, the web server in front of PHP and memory layout.
  • Privileges Required: None and User Interaction: None. No account and no victim action are needed.
  • Confidentiality, Integrity and Availability: High on the PHP server itself.

Running more workers makes an attack take more tries. It does not stop it.

CVE-2026-109618: Out of Memory Corruption in Request Startup

When PHP runs out of memory, it leaves the current code path with longjmp(). Some request data is reachable before it is fully set up. If any allocation fails in that window, request shutdown can later read that half built data as if it were valid. The allocation that failed does not have to be related to that data.

The method the advisory shows is pushing one request past memory_limit, and it works with default settings. A multipart body with no usable Content-Length gets past the first post_max_size check. A single multipart part can carry any number of headers, and they cost far more memory inside PHP than on the wire. Empty file fields build arrays without counting against max_file_uploads, and nested field names multiply that work.

On mod_php all of this happens during request startup, because that is when PHP parses the body, and mod_php runs shutdown even when startup fails. PHP-FPM ends the worker when startup fails, which is why it is harder to exploit there.

CVE-2026-109619: Stale Global State Across Requests

One PHP worker serves many requests. Error, session, object and extension state from a request can stay referenced after that request's memory is freed.

The attack uses two requests on the same worker. The first one leaves state behind that PHP never resets. Fatal errors do this, including parse errors, a failed require, uncaught errors and execution timeouts. So do out of memory errors, and warnings raised during cleanup after PHP has already cleared that state. The second request reaches code that reads the leftover state before request setup clears it. The advisory names two such places: warnings, notices or deprecations from INI settings applied before request startup, and session upload progress. The second request can then use freed memory.

Two defaults make this worse. Session upload progress is on by default and works without the application calling session_start(). In PHP 8.5, fatal_error_backtraces is also on by default. It stores backtrace state and always misses the reset, and it is the basis of the confirmed mod_php exploit.

Hiding errors does not help. PHP reads the stale state before it checks error_reporting, @, display_errors or log_errors.

Affected Systems and Versions

BranchAffectedFixed in
PHP 8.5Before 8.5.128.5.12
PHP 8.4Before 8.4.278.4.27
PHP 8.3Before 8.3.368.3.36
PHP 8.2Before 8.2.358.2.35. The branch reaches end of life on December 31, 2026
PHP 8.1 and olderAll versionsNo upstream release. Minimal source backports exist for 7.4, 8.0 and 8.1

Exposure depends on the server API that PHP uses to receive requests:

Server APICVE-2026-109618CVE-2026-109619
Apache mod_phpRCE confirmed over HTTP, before any application code runsRCE confirmed
PHP-FPMPossible, based on the source. FPM ends the worker when request startup fails, so an attack needs an out of memory error later, in application code. No exploit shownRCE confirmed through session upload progress on a normal pool, given a suitable application operation. Also possible when the web server passes PHP_VALUE or PHP_ADMIN_VALUE settings that raise a warning
FrankenPHPLikely without application code, based on the sourceThe INI warning path was not shown in the default setup. The advisory says this does not make it immune
LiteSpeed LSAPILikely in some applications, not testedPossible through INI values set by the environment

php.net also lists php-cgi as at risk. mod_php carries the highest risk according to the PHP security team.

Patch Information

PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix both vulnerabilities. Distribution and LTS vendor packages may already be available, since those vendors received the patches early. Users of rpms.remirepo.net should switch to distribution packages or build from source, because the PHP team says that repository will not have updates on release day.

For CVE-2026-109618, the fix removes longjmp() from out of memory handling. PHP now stops the request at the next safe point, and ends the worker with _exit() if memory keeps growing past a second, higher limit.

For 7.4, 8.0 and 8.1, the PHP security team published minimal source backports: 7.4, 8.0, 8.1. They turn off session upload progress and end the worker whenever it hits the memory limit. Moving to a supported branch or a vendor LTS build is the better path.

After updating, administrators should restart PHP-FPM, Apache or whatever runs PHP, so every worker loads the new build.

Detection Methods

Check the PHP Build That Serves Traffic

The php command line binary can be a different build from the one that serves web requests. Check the serving build directly:

php-fpm -v # often php-fpm8.3 on Debian and Ubuntu apachectl -M | grep -i php # mod_php loads as php_module

In containers, run the same commands with docker exec.

Review Error Logs for Stale State Producers

The CVE-2026-109619 advisory suggests turning on log_errors, a working error_log and error_reporting=E_ALL in an isolated environment, then reviewing the logs for fatal errors, timeouts and early INI warnings. The advisory also notes that clean logs do not prove a server is safe.

Mitigation Strategies

These steps block the known attack paths. Other variants may still work, and updating is the only full fix.

For CVE-2026-109618:

  • Set memory_limit=-1 with php_admin_value in the FPM pool or Apache config, and check that no pool, directory or application setting puts a limit back. Use a container or cgroup memory limit as an availability boundary instead, ideally one that kills only the affected worker. Do not use RLIMIT_AS or RLIMIT_DATA. They make allocations fail, which is what triggers the bug.
  • Set post_max_size to 8M, or 32M where uploads are needed, and keep upload_max_filesize below it. Lower max_input_nesting_level.
  • At the proxy, cap decoded body size, field count, multipart parts, headers and nesting depth, including for requests with no Content-Length. Block multipart forms where the application does not use them.

For CVE-2026-109619:

  • Set session.upload_progress.enabled=0 in php.ini, the FPM pool or the server config, then restart every worker. ini_set() cannot change this setting, and .user.ini applies too late.
  • On PHP 8.5, turn fatal_error_backtraces off with php_admin_flag in the FPM pool or Apache config, then restart every worker. A plain php.ini setting is not enough, because applications can turn it back on with ini_set().
  • Remove invalid or deprecated INI settings applied per request, and fix fatal errors and timeouts that an attacker can trigger.
  • Where performance allows, set pm.max_requests=1 so each FPM worker serves a single request.

Vendor Security History

PHP has shipped critical remote code execution fixes before, and attackers have used several of them. These earlier vulnerabilities are all in CISA's Known Exploited Vulnerabilities catalog:

CVEComponentVulnerabilityFixed inAdded to CISA KEV
CVE-2024-4577PHP-CGI on WindowsWindows "Best-Fit" character conversion lets an attacker pass command line options to PHP8.1.29, 8.2.20, 8.3.8June 12, 2024
CVE-2019-11043PHP-FPMCertain FPM setups write past allocated buffers, opening a path to code execution7.1.33, 7.2.24, 7.3.11March 25, 2022
CVE-2012-1823php-cgiQuery strings without an = are parsed as command line options, allowing code execution5.3.12, 5.4.2March 25, 2022

As of the catalog version released on October 21, 2026, CVE-2026-109618 and CVE-2026-109619 are not listed.

For this release, the PHP security team gave a day of advance notice, delivered patches to distributions and LTS vendors ahead of publication, and published minimal backports for 7.4, 8.0 and 8.1 even though the project no longer supports those branches.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization