Skip to main content
PHP2Shell (CVE-2026-109618, CVE-2026-109619): Patch Before the Bots Do

PHP2Shell (CVE-2026-109618, CVE-2026-109619): Patch Before the Bots Do

KU
• 7 min read•1 view

Two unauthenticated RCEs in PHP core, leaked a day before the patch, with exploit attempts already logged. Here is how to tell if you are exposed and what to do tonight.

Key takeaways

  • PHP2Shell is two unauthenticated remote code execution flaws in PHP core, CVE-2026-109618 and CVE-2026-109619, both CVSS 9.2.
  • Upgrade to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35 and restart every worker.
  • Apache mod_php is most exposed.
  • Config mitigations reduce risk but PHP says only the update is a complete fix.

Upgrade PHP to 8.5.12, 8.4.27, 8.3.36, or 8.2.35 and restart every worker, today. PHP2Shell is two unauthenticated remote code execution bugs in PHP core, rated CVSS 9.2. Apache mod_php is the worst case: the confirmed exploit fires during request startup, before your application code runs, so framework hardening never gets a say.

The timing is what makes this one dangerous. The CVE IDs leaked on October 20, PHP moved its release up a day to October 21, and Amazon's honeypots logged an exploitation attempt on October 17, four days before disclosure. Palo Alto's Unit 42 counts 22.6 million potentially exposed instances. Everything below is as of October 23, 2026.

Check if you're exposed in 30 seconds

You need two facts per host: the PHP version and the SAPI (how PHP is wired to the web server).

bash.bash
# Version and SAPI of the PHP your web server actually runs
$ php -v | head -1
$ php -r 'echo PHP_VERSION, " ", PHP_SAPI, PHP_EOL;'   # CLI view; check the web SAPI below
$ apachectl -M 2>/dev/null | grep -i php                 # php_module => mod_php
$ systemctl list-units --type=service | grep -i fpm      # php8.x-fpm => PHP-FPM

# Distro packages backport fixes without changing the upstream version
$ apt-cache policy php8.2-fpm libapache2-mod-php8.2     # Debian/Ubuntu
$ rpm -q --changelog php-fpm | grep -m3 -i 'CVE-2026-1096'  # RHEL family

# Containers: check the image, not the host
$ docker run --rm --entrypoint php your-app:prod -v

Two traps. First, the CLI php binary can differ from the one Apache or FPM loads, so confirm the web SAPI with a phpinfo() page on a private route or the FPM binary (php-fpm8.3 -v). Second, Debian, Ubuntu, and RHEL patch inside their own package versions. php -v printing 8.2.28 can be safe on Debian if the package changelog lists the CVEs. Trust the vendor advisory over the upstream number.

What the two bugs actually do

CVE-2026-109618, "RCE via OOM corruption." PHP handles out-of-memory errors with longjmp(), jumping straight out of whatever it was doing. In some spots, request memory is reachable before it is fully initialized. If any allocation fails right then, request shutdown later reads that half-built state as valid. The advisory lists several ways a multipart request can hit OOM while staying under post_max_size, including bodies with no usable content length and parts with unbounded header counts.

CVE-2026-109619, "RCE via stale global state." A worker keeps global pointers (error, session, extension state) into memory owned by one request. If a fatal error interrupts the cleanup, the request's heap is freed while the global still points at it. The next request on the same worker can touch that stale pointer before initialization resets it: a use-after-free. Session upload progress, which is on by default and needs no session_start(), is one confirmed path, and it was validated against both mod_php and FPM.

Which setups are most exposed

SetupStatus per PHP advisoryWhy
Apache mod_phpConfirmed RCE, default limitsShutdown runs even when startup fails; exploit runs pre-application
FrankenPHPLikely susceptibleSame unconditional shutdown as mod_php
PHP-FPMConfirmed via session upload pathChild exits on failed startup, but app-time paths remain
LiteSpeed (LSAPI)Conditional, unvalidatedModels FPM; app-specific exploits likely
php-cgiAt riskPHP lists every web-serving install as affected

If you can't patch tonight

PHP is blunt that updating is the only complete fix. If a rollout needs a day, apply these administratively (so applications can't override them) and restart every worker:

ini.ini
; /etc/php/8.3/fpm/pool.d/www.conf  (temporary, remove after patching)
php_admin_value[memory_limit] = -1
php_admin_flag[session.upload_progress.enabled] = off
; PHP 8.5 only, removes the confirmed CVE-2026-109619 producer:
; php_admin_flag[fatal_error_backtraces] = off

For mod_php, use php_admin_value and php_admin_flag in the Apache vhost instead. Then:

  • Cap request size at the front. Set client_max_body_size in nginx or LimitRequestBody in Apache, and block multipart bodies on routes that never take uploads.
  • Watch memory at the container level. memory_limit = -1 removes the predictable OOM the exploit relies on, but it also removes PHP's own guard. Give each worker its own cgroup limit if you can.
  • Do not use RLIMIT_AS or RLIMIT_DATA. It sounds like the safe way to cap memory. It makes mmap() fail, which triggers exactly the vulnerable longjmp() path.
  • Optionally set pm.max_requests = 1 if you can afford the performance hit, so no worker serves a second request with stale state.

Cloudflare and Palo Alto shipped WAF signatures. Cloudflare calls its rules "a STOPGAP only," and they cover only traffic that passes through them. Treat a WAF as time bought, not a fix.

End-of-life PHP has no release

PHP 7.4 through 8.1 get source backports only, with no official binaries. PHP 5.4 through 7.3 get nothing, and the vulnerable code goes back to 5.4.0. CISA recommends taking PHP systems offline if they can't be patched or run 8.1 or earlier. If you inherited a PHP 7.4 box, finish that upgrade this week. We wrote up how to triage vulnerabilities in production when the fix is not one command.

What attackers are doing

This is not theoretical. Amazon reported attempts from multiple actors by October 21, and Cloudflare and watchTowr both report early attacks. Unit 42 describes an agentic AI attack platform that went from initial access at a European government entity to password hashes and MFA secrets in under two hours, then tried an NTLM relay into Active Directory. Public proof-of-concept code is circulating, though PHP said it found no functional exploit at release. As of October 23, neither CVE is in CISA's Known Exploited Vulnerabilities catalog. KEV listing tends to lag, so don't wait for it.

After patching, check for signs of earlier compromise: unexpected child processes of php-fpm or httpd (shells, curl, wget), new files in web roots, and outbound connections from web workers. Rebuild and rescan container images too, since a patched host running an old php:8.3-apache image is still exposed. Our notes on container vulnerability scanning cover catching stale base images in CI.

Questions people ask

Is PHP-FPM affected by PHP2Shell?

Yes. FPM is harder to exploit than mod_php because it kills a child whose request startup fails, but PHP validated the session upload progress path for CVE-2026-109619 against a normal dynamic FPM pool. Upgrade FPM installs to a fixed release, and until then disable session.upload_progress.enabled administratively and restart the pool.

Does a WAF protect me from CVE-2026-109618?

Partly, and only temporarily. Cloudflare and Palo Alto deployed signatures for known vectors, but Cloudflare describes its rules as a stopgap, and they only see traffic routed through them. The bug lives in how PHP parses requests, so new variants can slip past signatures. Patch PHP and use the WAF to buy hours, not weeks.

Is PHP 7.4 vulnerable to PHP2Shell?

Yes. The affected code path dates back to PHP 5.4.0. PHP 7.4 through 8.1 receive source backports only, with no official release, and 7.3 and earlier receive nothing. Check whether your distro or an LTS vendor shipped a patched package; otherwise upgrade to a supported branch or take the host off the internet.

The decision, concretely

  • Running mod_php on the public internet? Patch now, and if you can't, take the site offline until you can.
  • PHP-FPM behind nginx? Patch this week at the latest; apply the pool mitigations today.
  • Distro packages? Patch through the distro and verify the CVE in the changelog, not the version string.
  • PHP 8.1 or older? No upstream fix; get on a supported branch or a vendor's LTS package.

The call we'd make

Treat PHP2Shell like a weekend-cancelling event if you run mod_php or FrankenPHP on the internet, and as a this-week patch for FPM. Upgrade, restart every worker, rebuild images, and then look back at your logs since October 17. The config mitigations are real but partial; anyone who stops there is betting their uptime on a bug class that has already produced two CVEs this month.

Sources

Explore topics:DevOps
React
Share this post
KU

Kiril Urbonas

AI Engineer

555 articles
View all articles by Kiril Urbonas

You might have missed

Evergreen posts worth revisiting.