PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix CVE-2026-109618 and CVE-2026-109619, two flaws that allow unauthenticated code execution, worst on mod_php. What changed, who is exposed, and what to do before the update lands.
What Was Released
The PHP security release arrived on October 21, a little ahead of the announced 14:00 UTC. The two advisories went up on GitHub at 13:34 UTC, and php.net published the releases shortly after. The fixed versions are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35.
Both vulnerabilities are rated critical, CVSS v4.0 9.2, and both allow unauthenticated remote code execution as the account the web workers run under.
| CVE | Advisory | Short name | Fixed in |
|---|---|---|---|
| CVE-2026-109618 | GHSA-w8hw-w9fx-j79w | RCE via OOM corruption | 8.2.35, 8.3.36, 8.4.27, 8.5.12 |
| CVE-2026-109619 | GHSA-6wmf-4rv5-p3rp | RCE via stale global state | 8.2.35, 8.3.36, 8.4.27, 8.5.12 |
The php.net release notes are blunt about it. There are no complete mitigations, and updating is the only safe choice. Our earlier note, written before the details were out, covers how to find every PHP you run, which is the first step either way.
Who Is at Risk
PHP's advisory names every installation that serves web requests, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. It puts the risk highest on mod_php, where a demonstrated exploit runs before any application code does.
| Server setup | What the advisories say |
|---|---|
| Apache with mod_php | Remote code execution confirmed for both flaws, triggered during request startup before the application runs |
| PHP-FPM | Code execution validated for the session upload progress path of CVE-2026-109619. For CVE-2026-109618, source analysis shows FPM is susceptible, but no complete FPM exploit has been demonstrated |
| FrankenPHP | Calls request shutdown unconditionally like mod_php, so source analysis says it is likely susceptible to application-independent attacks |
| LiteSpeed (LSAPI) | Modelled on FPM, with application-specific exploits likely but not validated |
The important line for anyone running mod_php is that application code offers no protection. The confirmed attack happens while PHP is still starting the request, so a firewall rule in the application, a framework's maintenance mode or a security plugin never gets a chance to run.
CVE-2026-109618, RCE via Out-of-Memory Corruption
PHP handles an out-of-memory error by jumping straight out of whatever it was doing and abandoning the request. The advisory explains that in some places, request memory is already reachable before it has been fully set up. If any allocation fails at that moment, even one unrelated to that memory, PHP leaves the request in an invalid state, and the shutdown code that runs afterwards treats the invalid state as real.
The attacker's job is to make PHP run out of memory at the right moment while staying inside the limits it normally enforces. The advisory lists several ways multipart form requests can do that.
- A multipart request without a usable declared content length can pass the initial
post_max_sizecheck and keep supplying body data. - A single multipart part can carry an unlimited number of headers, and PHP's internal representation of them uses far more memory than they take on the wire.
- Empty file fields do not count toward
max_file_uploads, yet still create the usual file metadata arrays, and nested field names multiply that work.
Under mod_php, Apache runs PHP's request shutdown even when request startup has failed, so the whole sequence completes before the application is involved. FPM instead kills a worker whose startup failed, which removes that exact path, but an out-of-memory error later in a request can still reach the same flaw.
The fix removes the jump for out-of-memory errors. PHP now raises a soft out-of-memory error at the next safe point, and ends the process immediately if memory crosses a second, higher threshold.
CVE-2026-109619, RCE via Stale Global State
A PHP worker keeps some global state between requests, such as error, session and extension state, that points into memory owned by a single request. That state has to be reset before the request's memory is freed. The advisory describes cases where it is not, so that the next request on the same worker reads freed memory before normal initialization replaces it.
Exploitation needs two halves. A producer leaves request-owned state behind, typically because a fatal error or an out-of-memory error abandoned an operation before its cleanup ran. A consumer in a later request on the same worker then acts on that stale state. The advisory confirms two consumers.
The first is any warning, notice or deprecation raised while per-request INI settings are applied, before the request is initialized. Under mod_php that means .htaccess and Apache php_value or php_flag directives. Under FPM it means PHP_VALUE and PHP_ADMIN_VALUE parameters sent by nginx or another frontend. Deprecated or invalid settings are enough, and the advisory notes that hiding diagnostics with error_reporting, display_errors or the @ operator does not help, because the stale state is touched before PHP decides whether to report anything.
The second is session upload progress, which can reach session handling before ordinary session initialization. It is enabled by default and needs no session_start() call in the application. Code execution through this path was validated against both mod_php and FPM.
On PHP 8.5, the advisory adds a confirmed case where fatal_error_backtraces stores backtrace state that is never reset. That is the basis of the confirmed mod_php exploit for this flaw.
How to Update
Move to 8.5.12, 8.4.27, 8.3.36 or 8.2.35. PHP says Linux distributions and LTS vendors received the patches in advance, so distribution packages may already be available, and checking your vendor is the first step.
One package source is a problem today. PHP warns that the volunteer-maintained rpms.remirepo.net will not have updates on October 21 and urges its users to switch to distribution packages or build from source.
After the package update, restart every PHP worker and every Apache instance running mod_php, because a running process keeps the old code until it is restarted. Then confirm what is actually running.
php -v
php-fpm8.3 -v
apt changelog php8.3-fpm | head -20
On distributions that keep their own version numbers, a changelog entry naming CVE-2026-109618 and CVE-2026-109619 is the proof, since php -v may still show the older base version. Container images have to be rebuilt on an updated base image, and anything built from source needs a rebuild against the new tarball.
PHP 8.1 and Older
PHP 8.1 and older get no releases from the PHP project. Some distributions and LTS vendors backport fixes, so those users should ask their vendor. Given the severity, the PHP security team also published minimal source backports for PHP 7.4, 8.0 and 8.1 as branches in the php-src repository, meant for people who build from source or have no LTS vendor. That is a lifeline, not a support plan, and PHP 8.2 itself reaches end of life on December 31, 2026.
If You Cannot Update Today
PHP lists measures that reduce exposure to specific attack paths. It is explicit that none of them make an installation safe, so they belong to the hours before an update, not instead of it.
Against CVE-2026-109618
- Set
memory_limit=-1in a way applications cannot override, such asphp_admin_valuein the FPM pool or the Apache configuration, and check that nothing puts a finite limit back. A failure in an underlying allocation can still reach the vulnerable path. - Keep
post_max_sizelow, 8M for applications without uploads and 32M where uploads are needed, withupload_max_filesizebelow it. Enforce limits on decoded body size, field count, multipart parts, headers and nesting depth at the web server or proxy as well, including for requests without a usableContent-Length. - A container or cgroup memory limit can serve as an availability boundary. Do not use
RLIMIT_ASorRLIMIT_DATA, which can cause exactly the allocation failure the flaw needs.
Against CVE-2026-109619
- Set
session.upload_progress.enabled=0inphp.ini, the FPM pool or the server configuration, then restart every worker.ini_set()and FPM's.user.iniapply too late. The advisory suggests keeping it off even after patching if you do not use the feature. - On PHP 8.5, set
fatal_error_backtraces=0and restart the workers. - Remove invalid or deprecated settings applied per request, such as old directives left in
.htaccessor frontendPHP_VALUElines. - Fix fatal errors and execution timeouts that an attacker can trigger, including in upload, import and cleanup code. Where performance allows,
pm.max_requests=1stops one request's leftovers from reaching the next.
An Order for Tonight
Not every server carries the same risk, and the advisories make the order clear. Servers running Apache with mod_php come first, because the confirmed attack there needs no application code at all. Next are FPM servers whose frontend sends PHP_VALUE or PHP_ADMIN_VALUE per request, and anything using session upload progress, since those are confirmed consumers of the stale state. Ordinary FPM pools behind nginx follow, then internal tools and staging servers that are not reachable from the internet.
Where an update cannot happen tonight, apply the stopgaps above to that server specifically, write down which ones, and remove nothing from the list until the patched version is confirmed running. A note that says which hosts are on stopgaps is what stops one of them from being forgotten once the urgency fades.
What the Leak Got Right
The details leaked a day before the release, and some of what circulated has now been checked against the advisories. Session upload progress, which several unofficial write-ups pointed to, is one of the confirmed paths for CVE-2026-109619, although it is not the whole story and does not cover CVE-2026-109618. Claims of a CVSS 10.0 were wrong, as both advisories score 9.2. The leak also changed the timing, since PHP had said it would release early if details became public, and the release did land ahead of schedule.
Checking Your Logs
The advisory for CVE-2026-109619 recommends an isolated audit with log_errors=On, a working error_log and error_reporting=E_ALL. Look for warnings and deprecations repeated before scripts run, diagnostics during cleanup, fatal and parse errors, Maximum execution time exceeded, and failures tied to routes or uploads an attacker controls. Fixing what turns up reduces exposure. A clean log does not prove safety, because past logs may have excluded deprecations, and a failure can happen before PHP writes anything.
Patching PHP across shared, Plesk and cPanel servers and checking that every worker restarted is routine work in our server management service.
Sources: php.net security advisory, GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp, PHP 8 ChangeLog
Or read how we handle it in Servers Management.
Related News
PHP Patches Two Critical Flaws on Wednesday. Prepare Today
The PHP security team will ship fixes for two critical vulnerabilities, both CVSS v4.0 9.2, on October 21 at 14:00 UTC. Details come with the release, so today is for finding every PHP you run and knowing where its update will come from.
SecurityGitLab Fixes Two 9.9 RCEs Any Signed-In User Can Trigger
GitLab 19.4.1, 19.3.3 and 19.2.7 fix eleven security issues. In the two rated 9.9, any signed-in user can run code on the server with a crafted regular expression in a CI/CD configuration. GitLab.com is already patched.
SecurityNext.js 16.3.6 Patches an RCE in next/og ImageResponse
Next.js 16.3.6 fixes a critical remote code execution bug in next/og ImageResponse. One thing your OG routes do decides whether you were exposed, and two days after release npm audit still had no record of it.