PHP2Shell is the name the press gave to two critical vulnerabilities in PHP itself, CVE-2026-109618 and CVE-2026-109619. Both allow unauthenticated remote code execution and are rated 9.2 on CVSS v4.0. The fix is to update PHP to 8.2.35, 8.3.36, 8.4.27 or 8.5.12. If your site runs PHP 8.1 or older, the PHP project no longer ships updates for it, and that is where the real work starts.
In the past week I dealt with this on several sites, and no two went the same way. On one server the update took about a minute. On a shared host the provider had already patched the web PHP, while the command-line PHP on the same machine was still 5.6. On a third site, the host's emergency protection broke the admin panel on the morning the advisory came out, before it was even published.
Below: how to check where you stand, what each situation takes, and why I call PHP2Shell not a bug but a bill for five years without updates.
In short. Updating WordPress or Bitrix fixes nothing here, because the bug is in PHP. The PHP team rates the risk highest for Apache with mod_php, where a demonstrated exploit fires before any application code runs, so a security plugin never gets a say. Temporary hardening exists, and the PHP team says plainly it doesn't make an installation safe. On a supported branch this is a short maintenance task. On PHP 7.4 or 8.1 it's a migration.
What is PHP2Shell and which sites are affected?
PHP published the advisory on October 21, 2026. In plain terms, the two bugs are:
- CVE-2026-109618, "RCE via OOM corruption": an out-of-memory error can interrupt PHP while internal request data is only half set up, and cleanup then treats that broken data as valid (GHSA-w8hw-w9fx-j79w).
- CVE-2026-109619, "RCE via stale global state": state that belongs to one request can outlive its memory, and the next request handled by the same worker may use it (GHSA-6wmf-4rv5-p3rp).
According to the PHP team, every installation that serves web requests is at risk: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. On October 26 CISA added both CVEs to its Known Exploited Vulnerabilities catalog, the list of bugs confirmed to be used in real attacks.
One thing that confuses a lot of coverage: CVE-2026-111497 is a different story. It is a bug in the Brotli decompression library. PHP rebuilt only its Windows packages for it, and per the PHP team the vulnerable code is reachable through the cURL extension when automatic response decompression is enabled. That's off by default in cURL, though applications and HTTP client libraries can turn it on.
How do you check your PHP version?
The version that matters is the one actually handling web requests. It isn't always the one you see first.
Check what the web server runs
- WordPress: Tools → Site Health → Info → Server shows the PHP version.
- Response headers: many servers report it in
X-Powered-By. On a cached site, add a throwaway query parameter so you get a fresh response from PHP, not a stored page. - phpinfo(): a one-line file with
<?php phpinfo();shows everything. Delete it right after. It's a gift to anyone scanning your site.
The console can lie to you
php -v over SSH runs the command-line binary, which can be a completely different PHP from the one the web server uses. On one shared host this week the web side was already on 8.2.35, and the CLI on the same server was PHP 5.6. PHP 5 has had no security fixes for years. The advisory lists only web-facing setups (FPM, mod_php, CGI and the like), but cron jobs and scripts run through it, so it belongs in the inventory.
One number is not always the full answer
Linux distributions and LTS vendors received the patches in advance, and their builds can keep an older version number after backporting a fix. If your server reports something like 8.3.x from a distribution package, check the vendor's security notice before assuming you are exposed or safe. On shared hosting, ask the host.
Three situations, three amounts of work
Your workload depends on one thing: how far you are from a supported PHP branch.
- A supported branch on your own server. On a Bitrix store with a CRM, updating from 8.3.31 to 8.3.36 meant installing packages from the repository the server already used and restarting Apache, about a minute of actual work. Then the checks: the module list was the same 59 before and after,
php.iniwas untouched, a custom opcache config survived while the package's new default landed next to it as.rpmnew, and key pages plus the admin panel returned 200. Cron imports got a separate check the next morning, because background jobs are where PHP problems surface last. - Shared hosting. Some hosts update supported branches on their own. On one Bitrix site the provider had already moved PHP-FPM to 8.2.35, which I confirmed from the response header on several pages with the cache bypassed. If yours has not, switch the version in the control panel or open a ticket.
- PHP 8.1 and older. The PHP project no longer ships updates for these branches. It did publish minimal source backports for 7.4, 8.0 and 8.1, which help if you build PHP from source and have no LTS vendor; distributions and LTS vendors ship their own patched packages, so ask yours. For a typical small site, the real fix is moving to a supported branch. Until then, the PHP team lists interim settings, with an explicit warning that "only an update is a complete solution":
; Based on the PHP advisory. Set at the server level (php.ini, FPM pool,
; Apache config), not via ini_set() or .user.ini, then restart every worker.
memory_limit = -1
post_max_size = 8M ; 32M if the site needs file uploads
upload_max_filesize = 4M ; must stay below post_max_size
session.upload_progress.enabled = 0
fatal_error_backtraces = 0 ; PHP 8.5 onlymemory_limit = -1 closes one attack path and opens the door to memory exhaustion, so a container or cgroup limit around the worker makes sense alongside it. Treat this block as a way to buy days, not months.
Will your host update it for you?
Maybe. But the host protects its own platform, your admin panel isn't its concern, and its emergency measures can break your site before any attacker gets to it.
On the morning of October 21, before the PHP team had published the advisory, a shared host restricted upload progress and blocked every POST request with the multipart/form-data content type. Nobody warned the site owner. On that Bitrix store, product cards in the admin panel stopped saving, because the edit form submits as multipart.
How to tell that the host is blocking requests, not your site
Two requests with curl settle it in a minute:
# A regular form POST goes through
curl -s -o /dev/null -w "%{http_code}\n" -X POST -d "a=1" https://example.com/
# 200
# The same POST as multipart/form-data is rejected
curl -s -o /dev/null -w "%{http_code}\n" -F "a=1" "https://example.com/?probe=test123"
# 403
# The probe never reached the site's access log,
# so the request was cut off before Apache and PHP
grep "probe=test123" /path/to/site/access.logThe 403 came from the host's nginx on every URL, static files included, and the marked request never appeared in the site's own log. That rules out .htaccess, the CMS and the site's security settings.
The host's support reply explained the logic: the restrictions were temporary, until patches came out and PHP was updated. Patches usually exist only for supported versions, so on older ones they couldn't guarantee a fix, and recommended PHP 8.2 or newer after checking compatibility. On a VPS, the risk and the update are entirely the owner's job.
In effect the host did what the PHP advisory suggests, only harder: instead of tuning upload limits, it shut multipart off completely. Fair from their side. Painful for a store that needs to edit products. On that site I updated PHP to 8.5.12, the latest fixed release, step by step, with a backup and a check at every stage.
What breaks when you jump to PHP 8?
WordPress or Bitrix core usually handles a new PHP version fine. What breaks is your own code and old plugins: custom modules, template overrides, event handlers written for PHP 7 and never touched since.
create_function()andeach()were removed in PHP 8.0. Code that calls them dies with a fatal error.- PHP 8 stopped quietly coercing types.
array_key_exists()onnullorcount()on something that is not an array now throws aTypeError, which in Bitrix often shows up as a 500 in the admin panel. - Passing
nullto built-in string functions is deprecated since 8.1, dynamic properties since 8.2. Deprecated warnings are noise to fix later. A fatal error is the outage.
The order that works for me: a copy of the site, the error log, then fatal errors one at a time, then cron jobs and imports separately, because they fail in the background long after the homepage looks fine. Two detailed walkthroughs: WordPress after a PHP 8.3 switch and legacy Bitrix on PHP 8.
Why does PHP2Shell cost some sites so much more?
Critical bugs happen in every branch of every language. This one would be a routine maintenance day if every site ran a supported PHP. It gets expensive only for sites that haven't been updated in five years.
Around ten of the client sites I look after run on Bitrix and WordPress and have not changed PHP versions in years. The reasons repeat: "it works, don't touch it," not knowing it matters, nobody responsible for it, no budget to pay someone who would be.
The strongest objection I hear: "We've been on PHP 7.4 for five years and never got hacked." True, and it made sense for a while. In my experience, most attacks on small sites came through plugins and site code, and a plugin update or a security plugin covered a lot of it. PHP2Shell sits below all of that. It fires before the application runs, so nothing installed inside WordPress or Bitrix gets a say, and the PHP project has no regular release to ship for 7.4.
The second objection: "The host will handle it." For supported branches, often yes. For old ones, the host wrote it plainly: no guarantees. And as the multipart story shows, the host's fix can cost you a working admin panel for a while.
The bill keeps growing on its own. A jump from 7.4 to 8.x breaks far more code than 8.2 to 8.3, because the big break came in 8.0, with more deprecations in 8.1 and 8.2. And PHP 8.2 itself reaches end of life on December 31, 2026, so today's "safe" version is two months from becoming tomorrow's old one. Small updates on a schedule cost less than one big update during a fire.
FAQ
Does updating WordPress fix PHP2Shell? No. The vulnerability is in PHP itself, so only a PHP update closes it. WordPress, Bitrix, plugins and themes are not involved.
Is PHP 7.4 affected by PHP2Shell? The PHP team published source backports for 7.4, 8.0 and 8.1, but no regular releases, because these branches are out of support. Unless you build PHP from source or have an LTS vendor, the fix is moving to a supported branch.
Will a security plugin or a WAF protect my site? A security plugin won't: it runs inside the application, and the demonstrated exploit fires before application code. Limits at the web server or proxy level, which the PHP advisory mentions, reduce exposure, but the PHP team is explicit that only an update is a complete solution.
What if my host still runs PHP 8.1? Ask whether they ship a backported fix for it. If not, plan the move to a supported branch, ideally 8.3 or newer given that 8.2 ends in December, and test it on a copy of the site first.
What if the site may already be hacked? An update closes the hole but does not remove what is already installed. Here is what a backdoor looks like after a "cleanup" and how to find it.