As we reported this morning, the NCSC and its US and EU counterparts are telling every organisation that runs PHP to patch two critical vulnerabilities this week – CVE-2026-109618 and CVE-2026-109619, now widely referred to by the shorthand “PHP2Shell”. That piece covered the headline warning. What it could not cover in full is the detail that actually determines what you need to do next: the exact versions that fix the problem, what happens if your server is running something older than those versions, which kinds of PHP setup carry the most risk, and the fuller story of how two researchers using AI models found a bug of this scale in a matter of weeks.
Both CVE-2026-109618 and CVE-2026-109619 carry a CVSS v4.0 score of 9.2, Critical. Both are memory corruption bugs in PHP itself, not in any particular application, and both can lead to unauthenticated remote code execution. Security firm Wiz demonstrated the flaws against a plain “Hello World” PHP page and against the latest container images of WordPress, Drupal and Joomla alike – proof that the application running on top makes no difference. Beyond running commands on the server, successful exploitation can also disclose the contents of memory, which may include passwords, tokens and API keys. The bug is not new: it appears to go back roughly a decade, to around PHP 5.4, and Wiz estimates that PHP powers around 70% of the web.
This follow-up fills in the parts of the story that matter most for deciding what to do today: the fixed version numbers, the end-of-life problem for older PHP branches, why patching WordPress or your plugins will not touch this bug, what the partial mitigations actually do and do not cover, how to find your real PHP version rather than guessing at it, and the fuller discovery story involving two independent AI-assisted research efforts.
The exact fixed versions
If you take one number away from this article, make it this table. PHP’s security team released four fixed versions on 21 October 2026, one for each currently supported branch. Anything older than these numbers, on a supported branch, is not fixed.
| PHP branch | Fixed version | Status |
|---|---|---|
| PHP 8.5 | 8.5.12 | Supported – update now |
| PHP 8.4 | 8.4.27 | Supported – update now |
| PHP 8.3 | 8.3.36 | Supported – update now |
| PHP 8.2 | 8.2.35 | Supported – update now |
| PHP 8.1 | No official release | End-of-life – source backport only, or upgrade to 8.2+ |
| PHP 8.0 | No official release | End-of-life – source backport only, or upgrade to 8.2+ |
| PHP 7.4 | No official release | End-of-life – source backport only, or upgrade to 8.2+ |
| PHP 5.x | Nothing available | End-of-life – upgrade is the only route |
PHP’s own advice is blunt: upgrade immediately, because “there are no complete mitigations.” The partial mitigations covered further down reduce risk; they do not fix the bug. If your website, portal or appliance is running PHP 8.2.35, 8.3.36, 8.4.27 or 8.5.12 (or anything newer released since), it has the fix. Anything below those numbers on a supported branch needs updating today. Anything on PHP 8.1 or older needs a different conversation, which is the next section.
If you are on PHP 8.1, 8.0, 7.4 or 5.x: there is no official fix
PHP 8.1 and every branch before it reached end-of-life before this advisory, which means PHP’s security team is not issuing an official patched release for them. That is a different situation from this morning’s advisory, which assumed a fix was simply a case of updating to the latest version of your branch. If your server is on 8.1, 8.0, 7.4 or an even older 5.x release, there is no equivalent “latest patched version” for you to move to within your current branch. Your options are a source backport, a backport from a commercial LTS vendor or your Linux distribution, or moving up to a supported branch (8.2 or later). For PHP 5.x specifically, nothing has been published at all; upgrading is the only route.
PHP’s security team has published minimal source backport branches for 7.4, 8.0 and 8.1, which means the fix exists in source form for those three branches, but applying it means building PHP from source yourself rather than downloading a ready-made package. That is realistic for a team with the skills and the time to do it, and unrealistic for most small businesses running a managed website. The more practical routes for an EOL system are:
- A commercial long-term support (LTS) vendor backport. Several companies offer extended support for end-of-life PHP branches, back-porting security fixes like this one into the version you already run. If you are deliberately staying on an older branch for compatibility reasons, this is usually the fastest safe option.
- A backport from your Linux distribution. Debian, Ubuntu and RHEL-family distributions sometimes maintain their own PHP packages for longer than the upstream PHP project does, and may ship a backported fix under the distribution’s own version numbering. Check your distribution’s security advisories directly rather than assuming the package version number alone tells you whether the fix is present.
- Upgrade to PHP 8.2 or later. This is the option PHP itself recommends, and the only one that puts you back on a branch that will keep receiving official security fixes going forward rather than relying on a one-off backport each time something like this happens. Our PHP upgrade service exists specifically for businesses stuck on 7.4, 8.0 or 8.1 who need a safe path to a supported version, including the compatibility testing that an old codebase usually needs before it will run cleanly on 8.2 or newer.
There is no credible argument for staying on PHP 5.x at this point. If any system in your estate – a legacy intranet tool, an old booking system, a forgotten microsite – is running PHP 5, it has had no official security attention for years and now has a confirmed, unauthenticated, remote code execution path with no vendor fix whatsoever. The honest options are: take it offline, or rebuild it on a current PHP version. Patching around the edges of PHP 5 for this particular bug is not realistically available.
Which server setups carry the most risk
PHP runs inside a web server through one of several interfaces, known as SAPIs (Server APIs). All of the common ones are affected by PHP2Shell, but they are not all affected equally, and knowing which one your server uses changes how urgently you should treat it.
PHP identifies Apache’s mod_php as carrying the highest risk of the group, because of how early in request handling it can be reached: the flaw can be triggered before your application’s own code has had a chance to run at all, which rules out most application-level defences as a backstop. mod_php is older technology, but it is still in active use on a meaningful number of smaller and legacy hosting setups, often ones that have not been touched since they were first configured. If you are not sure which SAPI your server uses, ask your host or developer directly – it is a one-line answer for anyone managing the server, and it changes how much extra caution the mitigations section below is worth applying in the meantime.
PHP-FPM is the SAPI most widely used on current, actively managed hosting, and it is just as affected as the others; being on FPM rather than mod_php is not a reason to relax, only a reason to expect that your host’s standard update process is more likely to already cover you. FrankenPHP and LiteSpeed are newer or less common entries on this list, and organisations running either should check with whoever maintains that stack specifically, since it is easy to assume a less familiar runtime has been handled when nobody has actually confirmed it.
Why updating WordPress and its plugins does not fix this
CVE-2026-109618 and CVE-2026-109619 are bugs in the PHP language runtime itself – the software that executes your website’s code – not in WordPress, Drupal, Joomla, a bespoke application, or any plugin. Wiz demonstrated both flaws against a bare “Hello World” PHP page with no application framework at all, and separately against current WordPress, Drupal and Joomla container images, with the same result each time. Updating the application that runs on top of PHP cannot touch a bug inside PHP itself, in the same way that updating a document you are editing does not patch a flaw in the word processor running underneath it.
This is the single most common misunderstanding we expect to see this week. A great many UK businesses run WordPress, and a great many of those will, entirely reasonably, update WordPress core, their theme and their plugins as their first response to any security advisory – because that is usually exactly the right move. For PHP2Shell, it is not enough on its own. The vulnerability lives one layer down, in the PHP interpreter that WordPress itself runs on top of. You can be running the newest version of WordPress, with every plugin fully current, on a server that is still running an affected PHP version underneath, and the site is still exploitable.
That does not mean WordPress is irrelevant here. Keeping WordPress, its plugins and its themes current remains good practice and closes off other, unrelated vulnerabilities, and WordPress’s own Site Health screen is one of the easiest places to check which PHP version your site is actually running (covered in the next section). We have published a dedicated page on fixing PHP2Shell on a WordPress site, which walks through checking your host’s PHP version via WordPress itself, getting your host to confirm or apply the update, and what to do if your host is slow to respond. The broader explainer, including the technical detail of both CVEs, is on our PHP2Shell explainer page.
The partial mitigations, and where they stop working
If you cannot update PHP immediately, PHP’s security team has published configuration changes that reduce risk for each vulnerability individually. They are explicitly described as partial: they narrow the window an attacker can use, they do not close it. Treat them as a bridge to patching, not an alternative to it.
| Vulnerability | Partial mitigation | Important limitation |
|---|---|---|
| CVE-2026-109618 (out-of-memory corruption) |
memory_limit = -1 combined with a low post_max_size / upload_max_filesize (for example 8M if you do not need uploads, 32M if you do); enforcing request size, field count and multipart part limits at the web server or proxy level; container or cgroup memory limits at the operating system level. |
Must be set with php_admin_value in the FPM pool or Apache configuration so individual applications cannot override it. Do not use RLIMIT_AS or RLIMIT_DATA to cap memory – PHP’s own guidance specifically warns against this approach. |
| CVE-2026-109619 (stale global state) |
session.upload_progress.enabled = 0; on PHP 8.5, also set fatal_error_backtraces = 0. |
Must be set in php.ini, in the FPM pool configuration, or in server configuration. Setting these with ini_set() inside application code, or in a .user.ini file, does not work for this mitigation. Hiding errors with display_errors, error_reporting or the @ operator does not help either. |
| Both vulnerabilities | Web application firewall (WAF) rules – Cloudflare deployed emergency WAF rules on 21 October 2026. | Temporary cover only, intended to buy time while you patch, not a substitute for it. |
The ini_set() and .user.ini point is worth repeating on its own, because it is the kind of detail that trips up a well-intentioned fix. A developer asked to “apply the PHP mitigations” under time pressure might reasonably reach for ini_set() inside the application, since that is how many other PHP settings get adjusted day to day. For this specific mitigation, that approach silently does nothing: the setting has to be made in php.ini, in the FPM pool configuration, or at the web server level, where it applies before the application ever runs and cannot be bypassed by it. If you or your developer have already “applied the mitigation” this week, it is worth double-checking exactly where that setting was made.
The same logic explains why the memory mitigation specifies php_admin_value rather than the ordinary configuration directive: an admin value is locked at the server configuration level and cannot be overridden by an individual application, a .htaccess file, or a careless plugin. Using the regular directive instead would leave the same loophole open that the mitigation is meant to close. None of this is a reason to avoid the mitigations – they are genuinely useful if you cannot patch today – but it is a reason to have whoever applies them confirm exactly where each setting lives, rather than taking “done” at face value.
How to check your real PHP version
Before you can tell whether you are exposed, you need your actual PHP version – not the version you assume is running, and not just the version a command line tool reports. This catches out more organisations than it should.
- Run
php -von the server. This gives you the command-line (CLI) version of PHP, which is useful but is not necessarily what your website runs. - Call
phpinfo()from a web page, then remove it. A temporary script that calls PHP’s built-inphpinfo()function shows the version PHP-FPM or your web server module is actually serving requests with. Delete the script again once you have the answer; leaving it in place is its own, unrelated information disclosure risk. - Check your hosting control panel. cPanel’s MultiPHP Manager or Plesk’s PHP settings will usually show you the exact version assigned to your site or domain, often letting you change it from the same screen.
- For WordPress specifically, use Site Health. Go to Tools > Site Health > Info > Server inside the WordPress admin area, which reports the PHP version the site is actually running on.
A server can easily have two different PHP installations: one that php -v reports on the command line, and a separate one that PHP-FPM or Apache actually uses to serve web requests. Checking only the CLI version and concluding you are safe is one of the more common mistakes we expect this week. Always confirm the version via phpinfo(), your control panel, or your application’s own reporting (such as WordPress Site Health), because that is the number that is actually exposed to the internet.
One more wrinkle applies if your server runs a Linux distribution such as Debian, Ubuntu or a RHEL-family release. Distribution packages sometimes keep an older-looking upstream version number even after a security fix has been backported into that package, because the distribution maintainers patch the code without bumping the version string to match the latest upstream release. A version number that looks unpatched on a distribution package is not proof that it actually is unpatched. Check your distribution’s own security advisory for this issue rather than relying on the version number alone, and if in doubt, ask your hosting provider or system administrator to confirm directly rather than guessing from php -v output.
Signs PHP2Shell may already have been used against you
Because credible reports describe exploitation attempts before the fix was even public, patching alone is not necessarily the end of the story for an internet-facing server. Wiz and CISA both point to a set of signs worth checking for on any system that was internet-facing before you patched it.
- Unusual multipart requests followed by memory-limit errors or repeated HTTP 500 responses in your web server or application logs.
- Unexpectedly large or malformed
PHPSESSIDcookies returned in responses. - Unexplained churn in PHP worker processes – workers restarting or cycling more than usual.
- PHP worker processes launching shells, spawning unexpected child processes, or downloading tools from the internet.
- New administrator accounts you did not create, unexpected files (including possible web shells), or unfamiliar scheduled tasks (cron jobs).
The practical conclusion from the detection guidance is straightforward: because exploitation preceded patching for at least some targets, a patched, internet-facing PHP server should still be checked for signs it was reached beforehand. Patching closes the door; it does not tell you whether anyone already walked through it. If any of the signs above turn up on a system that was reachable from the internet, treat it as a suspected compromise and investigate properly rather than assuming the patch alone has resolved things.
How the discovery unfolded
The sequence below draws together the discovery timeline as reported, including two independent research efforts that both used AI models to find essentially the same class of bug within weeks of each other.
Wiz’s own framing of what the AI-assisted approach achieved is striking: “A single researcher completed in a week what previously would have taken a world-class team months of work.” Put plainly: this was not discovered independently once, but twice, by two separate teams using two different AI models, within a matter of weeks of each other, on a bug class that had sat undetected in PHP for roughly a decade. Whatever changed, it changed for both sides at once – the same capability that let defenders find this bug quickly is available to attackers too, which is part of why the coordinated response from PHP, Wiz, Calif, OpenAI and the agencies listed above moved as fast as it did once the advance notice leaked.
What agencies are telling organisations to do
This morning’s piece covered the NCSC’s UK alert. The fuller picture, now that more detail has emerged, shows a genuinely global response, with some agencies going further than a standard “please update” notice.
The CISA position is worth sitting with for a moment, because it is more specific than a general offline recommendation: it explicitly treats PHP 8.1 and anything older as needing to go offline until updated, which lines up exactly with the end-of-life problem covered earlier in this article. If a government cybersecurity agency’s working assumption is that EOL PHP should not be reachable from the internet at all until it is dealt with, that is a reasonable benchmark for a UK SME to hold itself to as well, rather than treating an old, unsupported PHP install as a lower priority because “it has always worked fine.”
Where exposure concentrates, by setup type
The chart below is an indicative model, not measured data – our own estimate of how much work is typically needed to fully close off PHP2Shell on a given type of PHP setup, from a straightforward one-step update through to a longer remediation project.
The pattern mirrors the EOL problem: the top of the chart is dominated by situations where there is no simple update to apply, either because the branch is end-of-life, the SAPI is the highest-risk one, or nobody has yet confirmed the version in use. The bottom of the chart is the easy case – a modern setup where somebody has actually gone and checked the number, rather than assumed the morning’s advisory was handled because “we updated something.”
Assuming you are covered, versus checking
Assuming you are covered
Reasonable but risky this week
- “We updated PHP recently, so we’re fine” – without checking the exact version against 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35
- “We updated WordPress and our plugins this morning” – without touching the PHP version underneath
- Checking the CLI version with
php -vand assuming it matches the web version - Applying the mitigations with
ini_set()or a.user.inifile, which does not work for this issue - Not knowing which SAPI (mod_php, FPM, php-cgi, FrankenPHP, LiteSpeed) the server actually uses
- No check for exploitation that may have happened before the patch was applied
- EOL PHP (8.1 or older) left running because “it has always worked fine”
Checking properly
Where Cloudswitched web development takes you
- Exact PHP version confirmed against the fixed list, via phpinfo(), control panel or Site Health, not just
php -v - PHP version checked separately from any WordPress or plugin updates, because they do not touch the same layer
- SAPI identified (mod_php, FPM, php-cgi, FrankenPHP, LiteSpeed) so the right level of urgency is applied
- EOL branches (8.1, 8.0, 7.4, 5.x) flagged for a backport decision or an upgrade plan, not left as-is
- Mitigations, where used, confirmed as set in php.ini, FPM pool or server config – not ini_set() or .user.ini
- Internet-facing systems checked for the detection signs Wiz and CISA have published
- A documented, fixed PHP version on record for every site, portal and appliance, ready for the next advisory
The story at a glance
| Item | Detail |
|---|---|
| Severity | Both CVE-2026-109618 and CVE-2026-109619 score 9.2 (Critical) on CVSS v4.0 |
| Fixed versions | PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35, released 21 October 2026 |
| End-of-life branches | 8.1 and older get no official release; source backports exist for 7.4, 8.0 and 8.1; nothing for 5.x |
| Highest-risk setup | Apache mod_php, reachable before application code runs; FPM, php-cgi, FrankenPHP and LiteSpeed also affected |
| Application layer | WordPress, Drupal and Joomla all demonstrated vulnerable regardless of patching – the bug is in PHP, not the app |
| Mitigations | Partial only; must be set in php.ini / FPM pool / server config – ini_set() and .user.ini do not work |
| Discovery | Independently by Calif (with OpenAI’s Patch the Planet programme) and by Wiz Research, both using AI models |
| Disclosure | Advance notice given for 21 Oct 14:00 UTC; details leaked early on a Hacker News forum, forcing disclosure on 21 Oct |
| Exploitation | Early exploitation attempts reported by watchTowr, Cloudflare and VulnCheck; Amazon reported seeing attempts before disclosure |
| Agencies | NCSC, NHS England Digital (CC-4875), CISA, ENISA and NCSC-NL all issued guidance or warnings |
| Governments offline | Netherlands, Finland, France, Australia and Japan each took some services offline while patching |
| Immediate first step | Confirm your actual PHP version via phpinfo(), control panel or Site Health – not just php -v |
A practical checklist for UK SMEs
1. Find your real version. Check phpinfo(), your hosting control panel, or WordPress Site Health – not just php -v, which can differ from what the web server actually runs. 2. Compare against the fixed list. You need 8.5.12, 8.4.27, 8.3.36 or 8.2.35 (or newer). Anything below those numbers on a supported branch needs updating now. 3. If you are on 8.1, 8.0, 7.4 or 5.x, plan the move. Decide between a source backport, an LTS vendor backport, a distribution backport, or upgrading to 8.2 or later – and treat the system as needing to come offline in the meantime if it is internet-facing and cannot be patched quickly. 4. Do not stop at WordPress or plugin updates. They do not touch the PHP version underneath; check that separately. 5. If you cannot patch today, apply the mitigations correctly. Set them in php.ini, the FPM pool configuration, or server config – not with ini_set() or a .user.ini file – and remember they only reduce risk, they do not fix the bug. 6. Identify your SAPI. Ask your host or developer whether you run mod_php, FPM, php-cgi, FrankenPHP or LiteSpeed, and treat mod_php as the most urgent case. 7. Check for prior compromise on anything internet-facing. Look for the signs Wiz and CISA have published: odd multipart requests, malformed PHPSESSID cookies, unexplained worker churn, new admin accounts, or files you did not create. 8. Write the version down. Once confirmed, keep a record of the PHP version for every site, portal and appliance you run, so the next advisory is a lookup rather than an investigation.
This piece builds on this morning’s report on the coordinated warning, and sits alongside our growing set of PHP2Shell resources: the full PHP2Shell explainer and FAQ, our emergency PHP patching service for anyone who needs this handled today, a dedicated WordPress fix guide, our PHP upgrade service for businesses stuck on end-of-life branches, and our website security hardening service for the configuration work that reduces exposure to issues like this one going forward. For organisations working towards Cyber Essentials, this advisory sits within the scheme’s requirement to apply critical security updates promptly on internet-facing systems, and our vulnerability scanning and cyber security audit services can confirm what is and is not covered across your whole estate. If you suspect a system may already have been reached, our penetration testing team and wider IT support service can help investigate and remediate properly, and you can always talk to our team directly.
Need your exact PHP version checked and patched today?
The fixed versions are known, the end-of-life problem is real, and the mitigations only work if they are set in the right place. Cloudswitched’s emergency PHP patching service checks the real PHP version your websites, portals and appliances are running – not just what the CLI reports – confirms it against 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35, applies the fix or a safe upgrade path if you are on an end-of-life branch, and checks internet-facing systems for signs of prior compromise before closing the ticket.
Book a PHP2Shell exposure checkFrequently asked questions
Know your exact PHP version, not just the headline advisory
This morning’s warning told you to patch. This follow-up tells you exactly what to patch to, what to do if your branch is end-of-life, and why your WordPress update this morning probably was not enough on its own. Cloudswitched helps UK businesses find their real PHP version across every website, portal and appliance, apply the fixed release or a safe upgrade path where none exists, set the partial mitigations where they actually work, and check internet-facing systems for signs they were reached before the patch went in.
Talk to our team


