No Patch Is Coming for PHP 7.4, 8.0 or 8.1
On 21 October 2026 CISA published an alert on two remote code execution flaws in PHP core, CVE-2026-109618 and CVE-2026-109619, both rated CVSS 9.2, which let an unauthenticated attacker run code on a web-facing PHP runtime. CERT-EU issued advisory 2026-018 in the same week. Patched builds exist for the supported branches: PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. For PHP 7.4, 8.0 and 8.1 there is no patch, and none is coming. That second sentence is the whole story, and the CVSS score is the less interesting half of it.
What happened
Both flaws sit in PHP core rather than in an extension or a framework, so the affected surface is every common way of serving PHP: mod_php under Apache, PHP-FPM behind Nginx, php-cgi, FrankenPHP, LiteSpeed. No configuration of a web-facing runtime is quietly out of scope here. CISA and CERT-EU both say patch immediately, and exploit attempts have been reported, so the window is not theoretical.
A third issue, CVE-2026-115560, was disclosed on 23 October and has no patch at the time of writing. The only mitigation published for it is turning off upload progress tracking in php.ini:
session.upload_progress.enabled = 0One note on the numbers, because it shaped the first day of this for a lot of teams. Details leaked on Hacker News before the official release, and they carried a CVSS 10.0 figure. The official rating is 9.2. The difference changes nothing you would actually do, and it is worth mentioning only because someone in your company has seen the 10.0 and someone else has seen the 9.2, and that mismatch will cost you half a meeting.
What to do today if you stay on PHP
Four things, in this order.
Move to a patched build on a supported branch. If you are on 8.2, 8.3, 8.4 or 8.5, this is a point upgrade: 8.2.35, 8.3.36, 8.4.27 or 8.5.12. If you are on 7.4, 8.0 or 8.1, there is no point upgrade to take, and the smallest honest move is onto 8.2 or later, which for an old codebase is not a flag flip. More on that below.
Set session.upload_progress.enabled to 0 for the unpatched third issue, then confirm it landed in the configuration the runtime actually loaded, rather than in one of the several php.ini files on the box that nothing reads:
php -i | grep -i upload_progressVerify what your hosting vendor patched by asking for the version of the running binary, not by reading a status page. "We have applied the October PHP security updates" is a sentence. A version string is a fact. Ask for the fact.
Check every box, not every web server. The runtime that serves requests is usually the one that gets patched, and the one running cron and queue workers is usually the one that does not, because nobody files it under web-facing. It parses the same code with the same binary, and in most architectures it has broader database and secret access than the front end does:
php -v
php-fpm -vIf you run containers, that check belongs in the image build rather than on a live host. A patched host with an unpatched base image is one of the most common ways to be confidently wrong on a Wednesday afternoon.
The part that matters more than the score
A 9.2 is a bad week. An unsupported branch is a different class of problem, and it is not really a security problem at all: it is a stack decision that got made years ago by nobody making it. Nobody chose to run 7.4 in 2026. Each year the upgrade was deferred for a good local reason: a release was in flight, the person who knew the payment code was busy, a dependency had no 8.x version, the thing was working. All of those were reasonable at the time. The accumulated effect is a system where the upstream answer to a critical CVE is now "upgrade to a branch you cannot reach."
That is the structural fact worth taking out of this week. On a supported branch, a severe flaw costs you an emergency patch window. On an unsupported one, it costs you a project, under time pressure, scheduled by somebody else's disclosure calendar. This pair of CVEs will probably not be the last, and the next one arrives with the same non-answer.
So the useful question is not "how fast can we patch" but "is this a version jump or a stack jump." We have run that triage on enough inherited systems to trust four signals over anyone's instinct, including our own.
Size of the service, measured in surfaces rather than lines. Endpoints, scheduled jobs, queue consumers, admin screens, third-party integrations. A large codebase behind a handful of endpoints is small in the sense that matters here. A much smaller one wired into a dozen external integrations is not.
The ratio of framework glue to business rules. Glue is replaceable, and it is the cheapest part of any move because it is the part nobody has an opinion about. The rules that were never written down, how a refund is attributed, which state transition may be retried, why one customer tier skips a check, are the expensive part. They are expensive whether you move or stay, and moving is just when you find out.
Test coverage on the paths that touch money, authentication, and anything a regulator could ask about. Not the overall coverage percentage. If the money paths are covered, a migration is verifiable. If they are not, the first stretch of any plan goes into making them verifiable, and that work is not optional, because it is the only thing that lets you tell a successful cutover from a quiet one.
Who still knows it. Not who owns the repository, but who can explain why a particular branch in the code exists. If that is one person, the risk was already there and the CVE did not create it.
Small service, mostly glue, covered money paths, someone who still knows it: that is a version jump, measured in days. Large, dense with business rules, thin coverage, institutional memory gone: that is a stack jump, and treating it as a version jump is how a two-week estimate quietly consumes two quarters of everything else.
What an honest rewrite looks like
Scope first, and scope is cheap. A day of reading a service, its routes, its schema, its jobs, its integrations, its configuration, is enough to say what moving it costs and roughly how many weeks it takes. Anyone who gives you a number without that day has given you a number, not an estimate.
Strangler pattern, not big bang. The old service keeps serving traffic while a new one takes over one surface at a time behind the same entry point. On paper this looks slower. In practice it goes faster, because every step is independently shippable and independently revertible, and you are never holding a half-migrated system that cannot go to production.
Data model and the payment and authentication paths first. Those are the places where a subtle behavioural difference is both expensive and silent, so they get done while attention is highest and the old implementation is still running next door to compare against.
Keep the old service as the reference until parity. Running both and comparing behaviour on real traffic shapes is the only parity check we trust. A specification written by reading the old code is a hypothesis about the old code. When the new path matches on the cases that matter, the old one gets switched off, not before, and not because a date in a plan said so.
Small services move in days. Large ones move in planned weeks, with the weeks named up front and revised out loud if the reading was wrong. We have done this work on inherited systems before, including monolith-to-microservice splits and runtime migrations where the old branch had already stopped receiving fixes. The shape of the work being familiar is most of what makes an estimate honest.
If you are on an unsupported branch
Send us the service. Within one day we will tell you what moving it onto a supported, modern stack costs and how many weeks it takes. If the answer is that you should take the version jump and stay where you are, we will say that too, since it is frequently the right answer and it is cheaper for everyone involved.
Either way, patch what can be patched today. The 9.2 is this week. The branch with no patch is every week after it.