Published · Updated · Sources: php.net, Cloudflare, nodejs.org
On 21 October 2026 PHP fixed two critical flaws that let anyone on the internet run code on a PHP server without signing in. Cloudflare calls them php2shell and reports attacks already. This page lists only what the sources confirm. To see what your own site shows the world, run the free check: it takes ten seconds.
What happened
- PHP announced a critical security release for the next day: unauthenticated remote code execution, rated CVSS v4.0 9.2 (php.net).
- Cloudflare deployed firewall rules for the flaws, which it calls php2shell, on every plan with its WAF, the Free plan included. It reports attack traffic against its customers, and says the flaw leaked before the official release date (Cloudflare blog).
- PHP released 8.5.12, 8.4.27, 8.3.36 and 8.2.35, which fix CVE-2026-109618 and CVE-2026-109619 (php.net).
- Node.js shipped its October security releases the same day: 22.23.4, 24.22.1 and 26.12.1 (nodejs.org).
Some reports on social media go further; we only list what the sources above confirm.
Who is affected
Every server running a PHP release older than the fixed release of its branch. PHP's advisory names the ways of running PHP that are at risk: PHP-FPM, mod_php inside Apache (the highest risk), php-cgi, FrankenPHP and LiteSpeed.
That includes sites you may not think of as PHP: WordPress and WooCommerce, Drupal, Joomla, Magento, Laravel and most shared hosting. A headless site whose pages come from Next.js often has a WordPress behind it on another address, such as wp. of your domain; that server needs the update too.
PHP 8.1 and older get no official release with the fix. Only source backports exist for 7.4, 8.0 and 8.1. On those branches, plan the move to a supported one now.
If your site is hosted on a platform such as Shopify, Wix or Squarespace, the platform runs PHP for you and patches it; there is nothing for you to update.
Is my server patched?
Compare your version with the fixed release of its branch: 8.3.36 fixes 8.3, and 8.3.10 is not fixed even though it is newer than 8.2.35.
- On the server:
php -v. The command-line PHP can differ from the one serving your site; check the FPM binary too, for examplephp-fpm8.3 -v. - In WordPress: Tools › Site Health › Info › Server.
- From outside: the free check shows what your server tells anyone, with the proof for each finding. Most servers hide the version, which is good; then only the server can say.
What to do now
- Update PHP to the fixed release of its branch, then restart PHP: the FPM pool, or the web server when PHP runs inside it.
- Until you can update, PHP's advisory lists mitigations. They reduce the exposure; they do not make a site safe:
memory_limit=-1throughphp_admin_valuein the pool or virtual host;post_max_sizeto 8M (32M on a site that takes uploads);session.upload_progress.enabled=0, then restart the PHP workers;- on PHP 8.5,
fatal_error_backtraces=0; - at the proxy, limit the request size, the number of form fields and the number of multipart parts.
- Behind Cloudflare? Its rules help on plans with the WAF, and Cloudflare itself says customers should patch even with these protections.
- Node.js: update to 22.23.4, 24.22.1 or 26.12.1, rebuild the app's image if it runs in a container, and restart it. The highest of the ten fixes is rated High (CVE-2026-111497).
What scanners do to every site
Scanners do not wait for an advisory: they ask every server for secret and config files every day. Skald's own audited Security figures for one of our sites, this week:
| Day | Probes | From addresses |
|---|---|---|
| 17 Oct | 4,148 | 102 |
| 18 Oct | 2,487 | 147 |
| 19 Oct | 3,039 | 115 |
| 20 Oct | 1,085 | 104 |
That is between 1,085 and 4,148 scanner probes a day, from 100 to 150 different addresses, asking for files like /.env, SSH keys, cloud credentials and Terraform files. Some got a page back. We checked every probe that got a page back: each was the same harmless app page any unknown address gets.
Check your own log for probes
Your web server's access log has the same story. On a log in the common "combined" format, this lists the secret-file requests that got a 200, with the size of each answer:
awk '$9==200 && $7 ~ /\.(env|git|aws|ssh|sql|bak|tf|tfvars|key|pem)/ {print $7, $10}' access.log \
| sort | uniq -c | sort -rn | head
In that format $7 is the path, $9 the status and $10 the bytes sent. If every line shows the same size, the server answered all of them with one page, usually its harmless fallback page. A different size is worth opening yourself: it may be a real file.
Skald does this every day for every host, sets each answer against the host's own fallback page, and shows who is scanning you and which advisories apply to your stack. See Security in Skald.
Next step
Check what your site shows the world: your PHP, WordPress and Node.js versions as anyone sees them, with the proof for each finding and the commands to check it yourself. Run sites for clients? Check up to 10 at once, with one PDF for all of them.
Run it from your terminal or CI
The same check as a free command-line tool (MIT), one Python file with no dependencies, and a GitHub Action that can fail a build when an update is needed. github.com/spcaeo/php2shell-check
curl -sSL https://raw.githubusercontent.com/spcaeo/php2shell-check/main/php2shell_check.py | python3 - example.com
php2shell:
runs-on: ubuntu-latest
steps:
- uses: spcaeo/php2shell-check@v1
with:
url: example.com