CVE-2026-109619 is described in PHP's own advisory as remote code execution through stale worker state, and I keep rereading that phrase because it describes our deployment habits as much as it describes a bug. On October 21 the PHP project shipped 8.5.12, 8.4.27, 8.3.36 and 8.2.35, fixing that one plus CVE-2026-109618, an out-of-memory corruption path. Both carry a CVSS v4.0 score of 9.2 and both are reachable without authentication. My position is simple: the version list is the easy part of this week. The thing most teams cannot do, and should be embarrassed into learning, is prove which PHP build is serving each request on each host at this moment.

Look at how the fix actually reaches production. Your distro may backport it into a package that still says 8.5.4 or 8.3.something, so the version string tells you very little. Your container image may be patched in the registry while three replicas from August keep happily serving traffic. Your PHP-FPM master may have been upgraded on disk at 03:12 while its children still hold the old code in memory until somebody restarts the service. And the CLI binary you check with php -v over SSH can be a different build from the one Apache or FPM uses for the site. Wordfence makes that last point explicitly, pointing WordPress owners to Tools > Site Health > Info > Server instead of the shell, and honestly every framework shop could use an equivalent page.

The Wordfence Threat Intelligence team's lab results are worth reading closely, because they cut both ways. In a specially configured PHP 8.5.11 Apache lab, their proof of concept for CVE-2026-109619 went over plain HTTP and wrote a temporary text file, which is code execution by any definition. Against a normal optimized 8.5.11 build, the same request only crashed PHP. For CVE-2026-109618 they saw 8.5.11 fall over where 8.5.12 answered normally, and on a WordPress 7.1.3 stack with an affected Ubuntu 8.5.4 package they got failures and restarts in some setups, without reaching code execution themselves.

Here's the strongest case for relaxing, and I want to give it its full weight. If the public exploit needs a lab-tuned build to do more than crash a worker, then for a typical production box the realistic outcome today is a denial of service, and a lot of the proof-of-concept code going around is, by Wordfence's own account, incomplete or wrong. Panic patching on a Friday has its own failure modes, and anyone who has broken a checkout flow with a rushed restart knows that cost is real.

I still don't buy it. CrowdStrike says its unpublished exploit worked reliably on both Intel/AMD and Arm, including against freshly restarted workers, and PHP itself confirmed code execution for both bugs, with one 109618 path firing before WordPress even boots. That last detail matters for everyone, framework or not: no application firewall, no middleware, no clever request validator in your Laravel or Symfony kernel sees a request that detonates before your code runs. Exploits that only crash things this week are a reasonable forecast for what they become next week, and a crashing FPM pool under attack is already an outage you'll be explaining to someone.

So what I'd want from this incident is a habit. Treat "which PHP is live here, started when, from which package revision" as an observable fact you can query, the same way you can query which commit is deployed. Expose it on a health endpoint behind auth, log it at worker start, put the image digest in your metrics labels. The Go folks get to brag that a static binary makes this trivial, and fine, they have a point about that one thing, but we have opcache_get_status, php_uname, PHP_VERSION and the package manager, and gluing those together takes an afternoon. Do it before the next advisory, then sweep the staging sites and origin IPs Wordfence rightly calls out, and keep your web, PHP and firewall logs from 48 hours before the release onward in case you were late.

One more uncomfortable note for anyone still on 8.1 or older: the PHP project no longer ships releases for those branches, so your safety depends entirely on a vendor saying, in writing, that they carried both fixes. If you can't get that sentence from them, that's your answer, and the upgrade you've been postponing just got a deadline.

I'm curious how your teams handle this in practice. When a security release drops, how do you actually confirm that every running PHP process, across FPM pools, queue workers, cron containers and that one legacy VM, is on the fixed code, and how long did it take you this time?