The TL;DR: If PHP runs anywhere on your internet-facing infrastructure, upgrade it today.

PHP released emergency fixes for two critical remote code execution vulnerabilities, CVE-2026-109618 and CVE-2026-109619, on October 21, 2026 at 13:35 UTC. Both are rated CVSS v4.0 9.2, both are unauthenticated, and every PHP release from 5.4 onward is affected. Upgrade to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35 depending on which branch you are on. PHP 8.1 and older are end of life and get no official release, though your OS vendor may still ship a patched package. Exploit code was circulating before the patch existed, so this is work for today rather than this week. We are updating this page as the picture gets clearer.

Latest update: 13:35 UTC, October 21. The patches are out. The full log is in Updates below.

What to do right now

Find out which PHP version is running on every host you own that answers to the internet, then upgrade each one to the patched release for its branch.

Three things make this go wrong in practice, and all three are worth checking before you call it done.

The first is that the PHP version on your laptop is not the version in your production image. Check inside the thing that actually serves traffic. For a containerized application, docker run --rm <your-image> php -v tells you what you are really running, and bumping the base image tag is usually the whole fix.

The second is that application code cannot patch this. The vulnerabilities are in PHP itself, so the fix happens at the runtime or server level. There is no composer update, no framework release, and no change you can make inside your own codebase that closes it. If you are on managed hosting, your provider may be patching for you, and their status page is a faster answer than guessing.

The third is that one missed host is the same as no patching at all, which leads to the question most people are getting wrong today.

How do I know whether the PHP CVE affects me?

You are affected if PHP is running anywhere on anything you own that is reachable from the internet. That is a different question from what your product is written in.

If your company's application is Python, Go, or TypeScript, chances are you read a headline about PHP and reasonably conclude it has nothing to do with you. However, a good share of the time, PHP is running somewhere. A few examples of where PHP could be hiding: the WordPress install serving the marketing site, the admin panel a contractor built in 2023, the status page nobody has logged into since, the staging environment that was never decommissioned, or the one legacy service that still handles a webhook because moving it kept getting deprioritized.

CVE-2026-109618 does not care that the host it lands on is not your product. Unauthenticated remote code execution on a forgotten subdomain is still code execution inside your network, on a box that probably has credentials in its environment variables and a route to something that matters.

So today, it might be worth running an inventory exercise: check every domain and subdomain you own, every host behind them, and the PHP version on each. If that list takes more than an hour to produce, the list itself is the finding, and it will still be the finding after this pair of CVEs is closed out. The gap between what a team believes it runs and what is actually exposed under its domains is the reason a routine upgrade turns into an all-day fire drill.

Need help running an inventory of your dependencies? Fencer can scan and inventory your dependencies in minutes, and let you know which ones have potential vulnerabilities. Sign up for free

What to do if you cannot patch PHP in the next few hours

Your absolute top priority should be patching PHP, but a few things can help while you get the patch sorted.

Cloudflare has deployed WAF rules covering the known exploits, and they are available on every plan including the free tier. Free plans get the rules automatically. Pro, Business, and Enterprise plans need the managed ruleset turned on in block mode. This is the fastest thing you can do right now. Treat it as a few hours bought, because a rule written against known exploit payloads stops the exploits that are known.

At the web server level, the attack is triggered through multipart/form-data request bodies, so blocking that content type in nginx or Apache will stop it, at the cost of breaking file uploads. For an application that can live without uploads for an afternoon, that is a reasonable trade. Restricting a host to GET and HEAD requests has the same effect and the same cost.

In PHP configuration, disabling session.upload_progress.enabled and enabling session.use_strict_mode have both been recommended as hardening while you upgrade.

If a host holds sensitive data, cannot be upgraded today, and cannot sit behind a WAF, taking it off the internet is still the only certain answer.

If you are on PHP 8.1 or older

No official patch is coming, though your OS vendor may still ship a patched package. The branches are end of life. Your options, in the order we would work through them: move up to a supported branch today if the application will tolerate it, put the application behind a WAF with the rules enabled while you do that work, or take it off the internet if it handles anything you would not want an attacker reading. An end-of-life runtime on an internet-facing host was already a standing risk, and today it is an active one.

Why companies took their websites offline in response to the PHP CVE

The sequence here is unusual, and it explains a morning that otherwise looks like an overreaction.

Both vulnerabilities were under embargo, with coordinated disclosure scheduled for October 22 so that patches and details would land together. The embargo broke on October 20 when details and two proofs of concept went public ahead of the fix, along with an exploit tool. The result? The entire internet knew there was an unauthenticated remote code execution bug in PHP and nobody had a way to close it.

During a normal vulnerability disclosure you'd simply patch and move on. But here there was nothing to patch, so removing the application from the internet was the only guaranteed mitigation available. Cloudflare reported the first attack traffic at 07:43 UTC on October 21, hours before any fix existed, which is the part that made the cautious choice the correct one.

The risk profile also inverts from here. Until the release, the details sat with a small number of people and building a working exploit took effort. A patch is a map, and writing an exploit from a published diff is a short job for anyone motivated. The window that opened at 13:35 UTC is the dangerous one.

Updates

13:35 UTC, October 21. PHP released the fixes: 8.5.12, 8.4.27, 8.3.36, and 8.2.35. PHP 8.1 and earlier are end of life and receive no patch.

13:00 UTC, October 21. Neither CVE had been added to the CISA Known Exploited Vulnerabilities catalog. We are watching for that, because KEV addition starts a federal remediation clock and tends to be the point at which exploitation is formally confirmed.

07:43 UTC, October 21. Cloudflare reported the first observed attack traffic, before any patch existed. Cloudflare's WAF rules covering the known exploits went live for all plans including the free tier.

October 20. The embargo broke. CVE details and two proofs of concept were published ahead of the scheduled October 22 disclosure, along with an exploit tool circulating under the name php2shell, whose banner claimed coverage of every PHP release from 5.4.0 onward. The PHP security team published advance notice of an October 21 release and said it would ship earlier if details became public or exploitation appeared in the wild.

Sources