If your marketing site or app runs on PHP, find out which version is serving requests today. Two bugs in the PHP engine itself, nicknamed PHP2Shell, let an attacker run code on your web server without logging in first. They are CVE-2026-109618 and CVE-2026-109619, both rated 9.2 on CVSS v4.0.
The fixed releases landed on October 21: PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. CISA added both CVEs to the Known Exploited Vulnerabilities catalog on October 26, listing them under PHP Group and giving federal civilian agencies until October 29 to patch. Three days. That deadline has already passed.
WordPress, Laravel, a custom app, shared hosting, a managed host, a VPS you set up two years ago and forgot: if PHP answers HTTP on it, this applies. If you run Node as well, the same week produced Node2Shell, and the version check there is just as quick.
What broke
Both bugs are in how PHP handles fatal errors. Per the Unit 42 threat brief, CVE-2026-109618 comes from out-of-memory handling that jumps out of the normal control flow and leaves request memory uninitialized. CVE-2026-109619 leaves global pointers aimed at memory that has already been freed, which a later request on the same worker can read or branch on.
Datadog Security Labs notes that PHP's advisory lists memory disclosure as a confirmed impact of CVE-2026-109619, and that every installation serving web requests is at risk: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, LiteSpeed. PHP rates mod_php as the highest risk of those.
This is not theoretical. Amazon Threat Intelligence recorded an exploitation attempt against its MadPot honeypots on October 17, four days before the patches existed, which Help Net Security covered on release day. Unit 42 put over 22.6 million potentially vulnerable instances on the internet at the time it published.
Finding the version that's actually serving your site
Running php -v on the box tells you about the command-line binary. That is frequently a different build from the one answering web requests, and Datadog calls this out specifically: check the runtime that serves your application.
- PHP-FPM:
php-fpm -v, or ask your process manager which binary the pool is running. - Apache with mod_php: find the loaded module with
apachectl -M | grep php, then check the version of the package that provides it. - Containers: the image tag in your Dockerfile is a claim, not a fact. Exec into the running container and ask it.
- Managed or shared hosting: the control panel has a PHP version selector. The number next to it is the one that counts.
One wrinkle: Linux distributions and LTS vendors got these patches ahead of public release and often backport fixes without changing the upstream version number. The same three digits can mean a patched build from your distro and an unpatched one compiled from source. Check your vendor's advisory and the package release, not just the version string.
Who patches the runtime
On managed WordPress hosting or shared hosting, the host patches PHP. Your job is to confirm they did, and to check whether your site is pinned to a branch they no longer ship fixes for. Plenty of sites are still parked on 7.4 or 8.0 because a plugin broke once in 2023.
That pin is a problem now. The Tenable FAQ says PHP published no official release for 7.4 through 8.1, only minimal source backports for people who build from source. PHP 5.4 through 7.3 get nothing from the project at all.
On a VPS or EC2 instance you own, you patch it. On a platform-as-a-service or anything containerized, you rebuild the image and redeploy, because the running container keeps the old interpreter no matter what the registry says.
Then restart. The Tenable FAQ is blunt about this: installing updated packages does not patch PHP processes that are already running. PHP-FPM, Apache and the rest hold the vulnerable code in memory until they are restarted. A patch you never reloaded is not a patch.
Worth knowing before you roll: PHP developers confirmed a regression in 8.4.27 and 8.5.12 that can crash processes in some applications using the SimpleXML extension. PHP traced it to a separate garbage collector change rather than the security fixes. Patch anyway, and watch your error log for a day.
Why your version string is a gift to whoever is scanning
PHP ships with expose_php turned on, which adds a header like X-Powered-By: PHP/8.3.35 to every response. One request reads it. An unhandled error page with display_errors left on can do the same, plus file paths.
That header does not make you exploitable. It makes you sortable. On October 21, the useful question for an attacker was not "who runs PHP" but "who runs PHP below 8.3.36", and a header answers it for free at internet scale. Our pen test flags exposed version strings for exactly this reason, and weeks like this one are the argument. There is more on what else your responses give away in our post on information leakage.
Set expose_php = Off and display_errors = Off, and log errors to a file instead. Do that after you patch, not instead of patching.
If you genuinely can't patch this week
PHP's own position, repeated by Tenable, is that updating is the only complete fix and configuration workarounds do not make an installation safe. With that said, here is what the official guidance actually recommends.
- For CVE-2026-109618, enforce
memory_limit=-1at the administrator level so applications cannot override it, and pair it with request limits at your frontend. Datadog adds a warning: do not reach forRLIMIT_ASorRLIMIT_DATA, because they can trigger the allocation failures the attack depends on. - For CVE-2026-109619, set
session.upload_progress.enabled=0, and on PHP 8.5 also setfatal_error_backtraces=0. Put both in configuration that loads before PHP parses the request, then restart every worker. - CERT-EU recommends isolating internet-facing applications until a fix is applied and verified. The UK NCSC went further and told organizations to consider taking offline any system that cannot be fixed right away.
- Cloudflare deployed WAF rules for known exploit vectors to all plans, including free. Cloudflare's own CTO calls it a stopgap, and it only covers traffic that actually routes through Cloudflare.
- Searchlight Cyber released php2shell-scanner, an open-source tool that tests whether a host is exposed to both CVEs. Point it at your own hosts.
The checklist
- Get the version of the runtime serving HTTP, not the CLI binary.
- Patch to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or to your distribution's patched build.
- Restart every worker: PHP-FPM pools, Apache, containers, anything still holding the old interpreter.
- Verify from outside, then re-check the control panel on hosts you do not control.
- On 8.1 or older, start the upgrade now. No official release is coming for you.
- Turn off
expose_phpanddisplay_errors. - If you were exposed and out of date, read your access logs and rotate secrets. Memory disclosure is a confirmed impact, so session keys and API tokens are in scope.
- If you cannot patch, apply the interim settings above and seriously consider pulling the app off the public internet until you can.
Two weeks from now
The servers that get hit are not the ones whose owners read an advisory on day one. They are the forgotten staging box, the client site nobody has invoiced since 2024, the VPS that only exists because someone needed a contact form to work.
The free scan will tell you what a domain is advertising about itself, version strings included. A $495 pen test goes further, with a person looking at the findings and at the old runtimes and frameworks still reachable from outside.