🛡️ Critical PHP vulnerability (PHP2Shell): how to tell if your site is affected and protect it
🌐 Français · English · العربية
Two critical PHP vulnerabilities let an attacker run code on a server without any credentials. Here is how to check in a few minutes whether your site is affected, fix it properly, and never be caught off guard by the next one.
Updated: 22 October 2026
In short
- On 21 October 2026, PHP fixed two critical vulnerabilities (CVE-2026-109618 and CVE-2026-109619, nicknamed "PHP2Shell") that allow remote code execution without authentication.
- Fixed versions: 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Anything older is affected.
- Every site that runs PHP is concerned: WordPress, WooCommerce, PrestaShop, Laravel, custom sites.
- Updating is not always enough: you also need to restart PHP, otherwise the old version stays in memory.
- On a server I manage, the fix was applied the day after the announcement and every site was checked one by one. This guide follows exactly that method.
1. What happened
On 21 October 2026, the PHP team published a security advisory titled "critical remote code execution vulnerabilities, update now". It fixes two separate flaws, each rated 9.2 out of 10 (CVSS v4):
| Vulnerability | What it is (no technical detail) | Official advisory |
|---|---|---|
| CVE-2026-109618 | Internal data corruption when PHP runs out of memory | GHSA-w8hw-w9fx-j79w |
| CVE-2026-109619 | Internal state that survives from one request to the next | GHSA-6wmf-4rv5-p3rp |
What they allow: under certain conditions, a single request sent to your site, with no account or password, can make the server run code with the site's permissions. In plain terms: site takeover, database theft, malicious pages planted on your domain.
Who is exposed: according to the official advisory, every PHP installation that serves web requests, whatever the mode: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, LiteSpeed. The PHP team considers the risk highest with mod_php.
Why it is urgent: the vulnerability identifiers leaked on a forum the day before the official release, before the embargo ended. Once a flaw this serious is public and the patch is available, others can study the changes and try to exploit them. It is safer to assume that the bots scanning the Internet for unpatched servers will pick it up quickly.
Fixed versions:
- PHP 8.5 → 8.5.12
- PHP 8.4 → 8.4.27
- PHP 8.3 → 8.3.36
- PHP 8.2 → 8.2.35
What about older versions? PHP 8.1 and earlier no longer receive official updates. The PHP team still provided minimal fixes for 7.4, 8.0 and 8.1 to Linux distributions and vendors offering extended support. In practice, if your server uses the PHP shipped by its Linux distribution (AlmaLinux, Rocky, Red Hat, Debian, Ubuntu…), what matters is the distribution package update, not the version number shown. For example, AlmaLinux released an update of its PHP 8.0 package fixing both flaws on 21 October, while the "8.0.30" number did not change.
Key point. PHP 8.2 reaches end of life on 31 December 2026. If you are still on 8.2 or older, this is the right time to plan the move to 8.3 or newer.
2. Am I affected?
The answer depends on how your site is hosted. Find your case.
Shared hosting (cPanel, Plesk, hPanel…)
This is the most common case for small sites. You do not manage the server: your host installs PHP patches. Your part:
- Check the version selected for your site in the control panel: "Select PHP Version" or "MultiPHP Manager" in cPanel, "PHP Settings" in Plesk, "PHP Configuration" in hPanel. Note the branch (8.1, 8.2, 8.3…).
- If you are on 8.1 or older, move to 8.3 or newer, after checking that your theme and plugins support it (see below).
- Write to your host's support: "Have you applied the PHP patches of 21 October 2026 (CVE-2026-109618 and CVE-2026-109619) on my server?". A serious host answers clearly and quickly. If they do not know what you are talking about, that tells you a lot about their reliability.
WordPress site
In your dashboard: Tools → Site Health → Info → Server. The "PHP version" line shows the version your site uses. On shared hosting, this number does not always tell you whether the patch is applied (see the note on distributions above): when in doubt, ask your host.
Before switching PHP branches, make sure your theme and plugins are up to date, and take a backup. Plugins abandoned for years are often the ones that block a move to a recent version.
VPS or dedicated server
You are the administrator: it is up to you. The main trap is that a server can have several PHP versions installed at the same time, and php -v only shows the command-line version, not necessarily the one serving your sites.
Check in this order:
1. Installed versions:
# AlmaLinux, Rocky, Red Hat
rpm -qa | grep -E '^php[0-9]*(-php)?-(common|fpm)'
# Debian, Ubuntu
dpkg -l | grep -E 'php[0-9.]*-(common|fpm)'
2. Running PHP-FPM services (they are what actually runs your sites):
systemctl list-units --type=service --state=running | grep -i php
3. Which version serves each site: look in your web server configuration to see which PHP-FPM "pool" each site sends its requests to, then which version that pool belongs to. In a panel such as Virtualmin, cPanel or Plesk, this is also shown in each domain's settings.
4. Available updates:
# AlmaLinux, Rocky, Red Hat
dnf check-update 'php*'
# Debian, Ubuntu
apt update && apt list --upgradable | grep -i php
If a PHP update is offered, consider yourself affected until proven otherwise.
The habit to drop: the public phpinfo page
To find their version, many people create an info.php file containing phpinfo(). Never leave it online. This page shows the exact version, extensions, server paths and part of the configuration: a valuable map for an attacker. If you must use it, do it for a few seconds, then delete the file. WordPress's Site Health screen or the command line are much better options.
3. Fix it
Update
On a VPS, it takes one command:
# AlmaLinux, Rocky, Red Hat
dnf upgrade 'php*'
# Debian, Ubuntu
apt update && apt install --only-upgrade 'php*'
Before that, if you run important sites, take a backup (database and files). A patch update within the same branch (for example 8.3.35 to 8.3.36) very rarely breaks anything, but a backup only costs a few minutes.
Restart PHP: the step everyone forgets
Installing the new packages does not replace the PHP that is already running: active PHP-FPM processes keep the old, vulnerable version in memory, sometimes for weeks. You must restart each PHP-FPM service:
systemctl restart php-fpm # the exact name depends on your setup
systemctl restart php8.3-fpm # Debian, Ubuntu
With mod_php, restart Apache.
Then check that the running processes started after the update:
ps -eo pid,lstart,cmd | grep "php-fpm: master"
The start time must be later than the update. On Red Hat-based systems, dnf needs-restarting -s also lists services still using old versions.
Check every site
Do not stop at the home page, which is often served from a cache. For each site, test:
- the home page;
- a page that really runs PHP: the admin login (
/wp-login.phpfor WordPress), the cart or checkout page of a shop; - that no error appears in the site's error log.
On a server I manage, I compared each site's response before and after the update: everything was identical, and no error appeared in the logs.
4. Mitigate if you cannot update right away
The official advisory is clear: only updating fully fixes these flaws. The measures below reduce some attack paths; they do not make a server safe. They are meant to hold for a few hours while you organise the update.
- Disable upload progress tracking (for CVE-2026-109619): in
php.inior the PHP-FPM pool configuration,session.upload_progress.enabled = 0, then restart all PHP processes. The advisory says not to rely onini_set()or a.user.inifile, which apply too late. This feature is rarely used: the PHP team even recommends keeping it disabled after updating if you do not need it. - Limit request size (for CVE-2026-109618): a low
post_max_sizevalue, and request size limits at the web server or proxy level. - On PHP 8.5 only:
fatal_error_backtraces = 0, then restart the processes.
The official advisory also mentions other memory-related settings, but they have significant side effects: do not apply them without fully understanding their consequences on your server.
5. Was I compromised?
If your server was patched quickly, the risk is low. But if you stayed several days on a vulnerable version, take ten minutes to check a few signs, without panicking.
- Recent, unexpected PHP files, especially in image or cache folders:
find /path/to/site -name '*.php' -newermt '2026-10-20' -not -path '*/cache/*'
On WordPress, a PHP file in wp-content/uploads is almost always suspicious.
- Unknown administrator accounts: in WordPress, Users → filter by the Administrator role.
- Unknown scheduled tasks:
crontab -lfor each site user, and the/etc/cron.dfolder. - Logs: bursts of requests to strange addresses, unusual PHP errors around 20 to 22 October.
- Site behaviour: redirects to gambling or pharmacy sites, foreign-language pages indexed by Google, security alerts from your host.
If you find something: do not just delete the file. Put the site in maintenance mode, change every password (admin, database, FTP, hosting), restore a clean backup from before the incident if you have one, update everything, then monitor. If you are not sure, call a professional: a partial clean-up often leaves a backdoor behind.
6. Never be caught off guard again
Automatic security updates
On a server, turn on automatic installation of security patches:
- AlmaLinux, Rocky, Red Hat:
dnf-automatic, set to apply security updates; - Debian, Ubuntu:
unattended-upgrades.
The trap I discovered
On a server I manage, PHP does not come from the distribution but from a widely used third-party repository (Remi Collet's repository), which makes it possible to install several recent PHP versions. This repository ships fixes quickly, but does not tag them as "security updates" in the metadata that automatic tools read. As a result, an "install security updates only" setting would have skipped the PHP2Shell fix, while the server looked protected.
The solution I put in place, and recommend:
- a nightly job that applies the distribution's security patches and, explicitly, PHP package updates (
dnf upgrade --securitythendnf upgrade 'php*'); - an automatic PHP-FPM restart when PHP has been updated;
- a check of every site afterwards, with an alert if one of them stops responding.
Patch updates within the same PHP branch are designed not to break anything. Automating them is reasonable; branch changes (8.3 to 8.4, for example) remain a manual decision, after testing.
Follow the announcements
- the news on php.net, where security advisories are published;
- the list of supported versions, to anticipate end-of-life dates;
- the security announcements of your Linux distribution or your host.
Checklist
- [ ] I know which PHP version serves each of my sites, not just the command-line one.
- [ ] My sites run on 8.5.12, 8.4.27, 8.3.36, 8.2.35 or newer, or on a distribution package that received the fix.
- [ ] PHP-FPM (or Apache with mod_php) was restarted after the update, and I checked the processes' start time.
- [ ] I tested a page that really runs PHP on each site.
- [ ] No
phpinfo()file is reachable online. - [ ] If I do not use
session.upload_progress, it is disabled. - [ ] I checked for suspicious PHP files and unknown administrator accounts.
- [ ] Security updates are automatic, PHP packages included if they come from a third-party repository.
- [ ] If I am still on PHP 8.2 or older, I have planned the move to a supported branch.
FAQ
Is my WordPress site affected even if it is up to date?
Yes, potentially. The flaw is in PHP, the language WordPress runs on, not in WordPress itself or your plugins. A fully updated WordPress on a vulnerable PHP is still exposed.
Does my host take care of it automatically?
On shared hosting, that is their job, and serious hosts apply this kind of patch as a priority. But check: ask them explicitly whether they applied the 21 October 2026 patches. On a VPS or dedicated server, nobody will do it for you.
I updated PHP, is that enough?
Only if PHP was restarted afterwards. Until the PHP-FPM processes (or Apache with mod_php) restart, the old vulnerable version keeps serving your pages.
php -v shows an old version, am I necessarily vulnerable?
Not necessarily. First, this command shows the command-line version, which is not always the one serving your sites. Second, Linux distributions often patch their packages without changing the version number: the package date and details are what count.
Does disabling session.upload_progress protect me?
Only partly. The official advisory says it blocks the confirmed session-related attack paths for one of the two flaws, not the other variants, and nothing for the second flaw. It is a stopgap, not a fix.
I am still on PHP 7.4 or 8.0, what should I do?
These versions no longer receive official updates. If your PHP comes from a distribution offering extended support, check that its package received the fix. Otherwise, the real solution is to move to a supported version: plan for it, as old themes or plugins may need adjustments.
How do I know if someone tried to exploit the flaw on my site?
There is no simple, universal signature. Look for the signs of compromise described above (recent files, unknown accounts, scheduled tasks, abnormal behaviour). If you have serious doubts, have the server examined by a professional.
Sources
- php.net, security advisory of 21 October 2026
- php.net, PHP 8 changelog
- php.net, supported versions
- GitHub, advisory GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
- GitHub, advisory GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
- Rapid7, analysis of CVE-2026-109618 and CVE-2026-109619
- Datadog Security Labs, PHP2Shell
- WordPress, the Site Health screen
- dnf-automatic documentation
- Debian, automatic updates with unattended-upgrades
- Remi Collet's repository (PHP packages for Red Hat and derivatives)
Need help?
I can check and fix your server or hosting, set up reliable automatic security updates and monitor your sites day to day. See the maintenance and hosting service or get in touch. For a free first check of your domain, try the domain health check.