BREAKING: PHP2Shell lets attackers run code on PHP web servers with no login. Update PHP now (CVE-2026-109618, CVE-2026-109619)
How to fix CVE-2026-109618: upgrade PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, then restart Apache and PHP-FPM. PHP2Shell (CVE-2026-109618 and CVE-2026-109619) lets attackers run code on PHP web servers with no login. PHP 8.1 and older get no upstream fix.
Contents
Two bugs in PHP itself let an attacker run code on a web server by sending it crafted HTTP requests, with no login and before your application code even starts. They are CVE-2026-109618 and CVE-2026-109619, nicknamed PHP2Shell, both rated critical (CVSS v4.0 9.2). Details leaked on October 20, PHP shipped the fixes this morning, October 21, and hosting companies have already reported exploitation attempts. The fixed releases are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.1 and older get no fix from the PHP project. Because the bugs sit in the interpreter, it does not matter whether the site is WordPress, Drupal, Magento, Laravel or something you wrote yourself.
This is our operator read of the two PHP security advisories (GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp), the php.net announcement, Patchstack's live timeline and the CERT-EU advisory.
How to fix
Upgrade PHP to a fixed release from wherever you got it, then restart every process that runs PHP. A package upgrade without a restart leaves the old interpreter in memory.
| Branch | Fixed in |
|---|---|
| 8.5 | 8.5.12 |
| 8.4 | 8.4.27 |
| 8.3 | 8.3.36 |
| 8.2 | 8.2.35 |
| 8.1 and older | No fix from PHP. Only a distribution backport, or an upgrade to a supported branch. |
# Debian / Ubuntu (distro packages or the ondrej/php PPA)
sudo apt update
sudo apt install --only-upgrade 'php*'
sudo systemctl restart apache2 # mod_php
sudo systemctl restart 'php*-fpm' # PHP-FPM
# RHEL / Alma / Rocky / Fedora
sudo dnf upgrade 'php*'
sudo systemctl restart httpd php-fpm
# Official Docker images: pull the new tag, rebuild, redeploy
docker pull php:8.4-apache # or whichever tag you build FROM
docker build --pull -t my-app .
Distribution timing varies. Ubuntu marked both CVEs Critical on October 21 and its LTS PHP packages were still "Needs evaluation" when the upstream fix landed, so check your vendor's tracker (Ubuntu, Debian, Red Hat) and do not assume apt upgrade already pulled a patched build. On managed hosting, ask your host when they are rolling it out.
Confirm the fix is the one actually serving traffic
# CLI version (not always the same binary your web server uses)
php -v
# What the web server really runs: drop this in a temporary file, load it, then delete it
<?php echo PHP_VERSION, ' ', PHP_SAPI; ?>
# Any FPM worker or Apache child still on the old binary after the upgrade?
sudo lsof -n 2>/dev/null | grep -E '(php-fpm|apache2|httpd).*(deleted)' | grep -i php
If the last command prints anything, a process is still running the replaced binary or library. Restart it.
Can't patch yet
PHP is blunt about this: updating is the only complete fix. If you are waiting on a distribution or a host, these settings break the confirmed exploit paths without fully closing the bugs. Set them in server-level configuration, not .user.ini, and restart every worker.
; php.ini or FPM pool php_admin_value
session.upload_progress.enabled = 0 ; removes the session upload progress producer/consumer (CVE-2026-109619)
fatal_error_backtraces = 0 ; PHP 8.5 only, removes the confirmed backtrace producer (CVE-2026-109619)
memory_limit = -1 ; PHP's primary config mitigation for CVE-2026-109618, see the tradeoff below
The memory_limit=-1 mitigation removes the predictable per-request limit the confirmed exploit relies on. It trades RCE risk for memory-exhaustion risk, so put a hard size limit on request bodies at your reverse proxy at the same time. PHP specifically warns against using RLIMIT_AS or RLIMIT_DATA as a substitute, because they push PHP into the vulnerable path. If your app never takes multipart uploads, rejecting multipart POST bodies at the proxy or WAF removes the main remote trigger for the first bug. Cloudflare has shipped WAF rules for known vectors, but those only help if your origin accepts traffic exclusively from Cloudflare.
What the two bugs are
CVE-2026-109618, out-of-memory corruption. PHP bails out of a request with longjmp() when it runs out of memory. In a few places, request memory is reachable before it is fully initialized. If any allocation fails at that moment, the early exit leaves that memory half built, and request shutdown later reads it. The attacker's job is to make PHP run out of memory at the right time, and multipart parsing makes that easy: a part can carry an unlimited number of headers, empty file fields do not count toward max_file_uploads, and nested field names multiply the work, so a body that stays under post_max_size can still exhaust memory_limit. Under Apache mod_php this all happens during automatic body parsing, before any PHP script runs. PHP validated full unauthenticated RCE against mod_php with default limits.
CVE-2026-109619, stale global state. A PHP worker keeps some global state (error, session, object and extension state) that points into memory owned by one request. If a fatal error, including the out-of-memory from the first bug, interrupts a request before that state is reset, the next request on the same worker can touch freed memory before normal initialization replaces it. That is a use-after-free, and with a groomed heap it becomes code execution. The confirmed cases are the PHP 8.5 fatal_error_backtraces path and session upload progress, which is on by default and does not need the app to call session_start(). PHP validated the session path against both mod_php and FPM.
The fix replaces the out-of-memory longjmp() with a delayed soft limit and a hard _exit(), and resets the wider per-request global state at the request boundary.
Who is not in scope
- PHP that never answers HTTP requests. Cron jobs, queue workers and CLI scripts that read no attacker input are not reachable by the request paths described in the advisories. Patch them anyway on your normal schedule.
- Hosts already on 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or a distribution build that lists both CVEs as fixed.
- Not every SAPI is equally exposed. mod_php is the confirmed, application-independent case for both bugs. PHP-FPM kills the child when request startup fails, so the startup path of the first bug does not work there; PHP calls FPM susceptible from source analysis but has not shown a complete FPM exploit for it, while the session upload path of the second bug was validated on FPM. FrankenPHP is "likely susceptible" to the first bug. LSAPI is a candidate. "Less proven" is not the same as safe.
PHP 8.1 and older is very much in scope: the advisories list every version below the fixed releases as affected. It just has no upstream fix. If your distribution backports the patch, take it, then plan the move to 8.4 or 8.5. PHP 8.2 itself loses security support on December 31, 2026.
What this is not
This is not a one-packet worm: PHP rates both bugs high attack complexity, the second needs two requests to land on the same worker, and reliability depends on the build, extensions and allocator, but attackers can simply retry until they win.
Exploitation status
Patchstack says multiple hosting partners reported active exploitation incidents from 07:34 UTC on October 21, and Cloudflare's CTO said it was seeing early attacks. In its most recent timeline entry before the release, Patchstack said its own telemetry still showed probing only, with no hard evidence of breaches. watchTowr said it reproduced CVE-2026-109618 before the release, and Sansec expected mass exploitation within minutes of the patch going public. Several large sites, including the Dutch DigiD and MijnOverheid services, went offline as a precaution. Treat any internet-facing PHP host you have not patched as a target today.
Check whether a host was hit
- Look for child processes of
apache2,httpdorphp-fpmthat are shells,curl,wgetor interpreters. - Look for new
.phpfiles in web roots, especially upload and cache directories:find /var/www -name '*.php' -newermt '2026-10-20' -ls. - In access logs, look for bursts of large multipart POSTs to endpoints that do not take uploads, and in error logs for repeated "Allowed memory size exhausted" lines from the same client.
Patching does not remove a web shell that is already there.
References
Continue reading
All posts
BREAKING: Exploited PAN-OS bug gives attackers root on Palo Alto firewalls, now on CISA KEV (CVE-2026-0322)
How to fix CVE-2026-0322: upgrade PAN-OS to the hotfix for your train (12.2.4, 12.1.10-h2, 11.2.13-h3, 11.1.16-h3, 10.2.18-h12 and others). Attackers are using this admin-interface bug for root on Palo Alto firewalls and Panorama; CISA due date Oct 17.

BREAKING: Malicious HTTP/2 servers can crash curl during uploads (CVE-2026-92392)
How to fix CVE-2026-92392: upgrade curl and libcurl to 8.23.0 (or 8.14.3, 8.16.2, 8.20.2 on those branches, or your distro's patched build). A malicious HTTP/2 server can trigger a use-after-free during uploads in curl 8.12.0 through 8.22.0.

WordPress page template include hits CISA KEV
How to fix CVE-2026-87902: upgrade WordPress to 7.1.2 (or your branch patch).
