Two critical PHP core RCEs: what is exposed and the order to patch
On 21 October 2026 the PHP project released 8.5.12, 8.4.27, 8.3.36 and 8.2.35, and its advisory says plainly: update now. The releases fix two critical vulnerabilities that can allow unauthenticated remote code execution, and the advisory counts every PHP installation that serves web requests as at risk: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed. If you run Laravel, WordPress or anything else on PHP, this one is about the runtime under your code, not your code. Nothing in your application has to be wrong for it to apply.
What the two bugs are
CVE-2026-109618 is about out-of-memory handling. PHP can be interrupted by an allocation failure while internal request data is only partly set up, and the cleanup at the end of the request may then treat that half-built data as valid. The GitHub advisory adds that several multipart upload parsing paths can reach that out-of-memory state while the request still looks within its limits. CVE-2026-109619 is about stale state: something a request owns can outlive the memory behind it, and the next request handled by the same worker may use it before normal initialisation resets it.
The third-party pwn.watch tracker calls the pair "PHP2Shell", rates both CVSS 9.2, and says details came out early after an embargo leak. According to the same tracker, exploitation attempts were seen before and after the patch, watchTowr and AWS report active scanning, and appliance vendors such as QNAP were still preparing fixes. Those are the tracker's claims; the php.net advisory itself is what tells you what to install.
Which setups are most exposed
The risk is not the same for every server API. The GitHub advisory explains why: mod_php always runs request shutdown even when request startup failed, so running out of memory while parsing the body leads to invalid state being processed before any application code runs, and a working exploit was demonstrated there. PHP-FPM exits the child when startup fails, which removes it from the pool; FPM is still susceptible by source analysis, but no complete FPM exploit was shown. FrankenPHP is likely susceptible in the same way as mod_php, and LiteSpeed's LSAPI behaves like FPM.
Find every PHP you run, then patch in order
As a general rule, a server can have more than one PHP on it, and php -v in a terminal reports the command-line binary, which is not always the one the web server uses. Check each place a version can hide: the CLI, the FPM service, every Docker image you build or pull, and the PHP selector in a hosting panel.
# the command-line PHP (may differ from the web one)
php -v
# the PHP inside a container image you deploy
docker run --rm your-image:tag php -v
For the version the web server really runs, a temporary file answers it in one request. Delete it straight after.
<?php
echo PHP_VERSION, ' ', PHP_SAPI;
Anything below 8.2.35, 8.3.36, 8.4.27 or 8.5.12 is affected. Linux distributions and long-term support vendors received the patches in advance, so check your vendor's packages first. The advisory notes that the volunteer-run rpms.remirepo.net would not have updates on release day, and suggests distribution packages or a source build instead. PHP 8.1 and older get no updates from the PHP project; some vendors backport, and the security team published minimal source backports for 7.4, 8.0 and 8.1 for people who build from source.
After the update, restart every PHP worker. A long-running FPM pool or a FrankenPHP worker keeps the old binary in memory until it is restarted.
What the mitigations do and do not do
The advisory is direct about this: updating is the only complete solution, and the measures it lists reduce exposure to specific paths without making an installation safe. For the out-of-memory bug they include setting memory_limit=-1 where applications cannot override it (php_admin_value in the FPM pool or Apache config), a low post_max_size (8M without uploads, 32M with them, and upload_max_filesize below it), limits at the web server or proxy on request size, field count, multipart parts, headers and nesting, and a container or cgroup memory limit rather than RLIMIT_AS or RLIMIT_DATA, which can cause the very allocation failure in question. For the stale-state bug: session.upload_progress.enabled=0 in php.ini or the pool config (not ini_set() or .user.ini) with every worker restarted, fatal_error_backtraces=0 on 8.5, removing invalid or deprecated per-request settings, and fixing fatal errors and timeouts an attacker can reach.
Today's concrete step: list every server, container image and hosting account that runs PHP, record the version each one serves, and update the ones below the fixed releases before you touch any setting. Source: php.net, security advisory of 21 October 2026.
Notes from readers