Skald

php2shell: is your site exposed?

Two critical PHP flaws were fixed on 21 October, and attacks have already started. Check what your site shows the world in 10 seconds.

We read your home page once, like any visitor. The check keeps nothing, but the site you check is in our server log (14 days). Privacy

For agencies: check up to 10 client sites, one PDF

Or run it from your terminal or CI: php2shell-check on GitHub

· Sources: php.net, nodejs.org

What happened

On 21 October 2026 the PHP project published fixes for two critical flaws, CVE-2026-109618 and CVE-2026-109619. They let anyone on the internet run code on a server that runs PHP, without signing in: no password, no account, just a crafted request. PHP rates them critical (CVSS v4 9.2).

Critical

PHP: fixed releases

Update to at least

  • 8.5.12
  • 8.4.27
  • 8.3.36
  • 8.2.35

Pick the release of your branch: a server on 8.3 needs 8.3.36 or later. PHP 8.1 and older have no official release with the fix; only source backports exist for 7.4, 8.0 and 8.1.

Read PHP's announcement on php.net

High

Node.js: fixed releases

Update to at least

  • 22.23.4
  • 24.22.1
  • 26.12.1

Ten fixes in one release. Branches past their end of life get none: move to 22, 24 or 26.

Read the releases on nodejs.org

Am I affected?

If your site runs on PHP and its version is older than the fixed release of its branch, yes. PHP's advisory names the ways PHP is run that are exposed: PHP-FPM (behind nginx or Apache), mod_php inside Apache (the highest risk), php-cgi, FrankenPHP and LiteSpeed. Between them, that is almost every PHP site.

You may run PHP without thinking of it as PHP. WordPress, WooCommerce, Laravel, Magento, Drupal, Joomla and most shared hosting plans all run on it. A "headless" site whose pages come from a JavaScript framework often still has a WordPress behind it, on another address such as wp. or cms. of your domain: that server needs the update too.

The check above reads what your home page tells anyone: the Server and X-Powered-By headers, the generator tag WordPress adds, and the paths in the page. If your server names its PHP version, you see at once whether it is below the fix. If it hides the version, that is good practice, but it does not make the server safe: you need to look on the server itself.

How to check your PHP version

  • On the server: run php -v. The command-line PHP can differ from the one serving your site, so also run the FPM binary your site uses (for example php-fpm8.3 -v), or ask your host.
  • In WordPress: Tools › Site Health › Info › Server shows the PHP version your site runs on.
  • In a hosting panel: cPanel shows it under MultiPHP Manager or Select PHP Version; Plesk under PHP Settings for each domain. Managed hosts usually show it on the site's dashboard.
  • Node.js: node -v on the server, or the base image in your Dockerfile (node:22 follows the branch; a pinned tag needs a rebuild).

Then compare: same branch, at or above the fixed release. 8.3.36 fixes 8.3; 8.3.10 does not, even though it is newer than 8.2.35.

What to do now

  1. Update PHP to the fixed release of its branch, then restart PHP: the FPM pool, or the web server when PHP runs inside it. On a managed host, ask them to confirm the date they updated.
  2. On PHP 8.1 or older, plan the move to a supported branch now. There is no official fixed release for those branches.
  3. Until you can update, PHP's advisory lists mitigations. They reduce the exposure; they do not make a site safe:
    • set memory_limit=-1 through php_admin_value in the pool or virtual host;
    • set post_max_size to 8M (32M on a site that takes uploads);
    • set session.upload_progress.enabled=0, then restart the PHP workers;
    • on PHP 8.5, set fatal_error_backtraces=0;
    • at the proxy, limit the request size, the number of form fields and the number of multipart parts.
  4. Keep the version hidden once you are updated: expose_php = Off in php.ini removes X-Powered-By, and server_tokens off; stops nginx naming its own version.
  5. Close the WordPress login page to the world if you can: allow only your own addresses, or add a second factor.

Node.js fixes the same day

The same day, Node.js shipped its October 2026 security releases: ten fixes, the most serious a flaw in the Brotli decoder (CVE-2026-111497) that can let a crafted request run code on the server. Others concern DNS lookups, TLS hostname checks and keep-alive connections. The fixed releases are 22.23.4, 24.22.1 and 26.12.1. A Next.js site runs on Node.js, so the check above flags Node.js whenever it sees Next.js. Update Node.js, rebuild the app's image if it runs in a container, and restart it.

What this check can and can't see

This reads only what your home page shows anyone. It can't see inside your server, and it doesn't test for the flaw.

  • One look, like a browser: your home page, then, for a WordPress host of your own domain, its login page, /xmlrpc.php, /readme.html, /wp-json/ and home page. Eight requests at most, each listed in the result: never a secret file, a user list or a form sent. No attack, no password, no form sent.
  • Proof for every finding: the exact header line or page reference we read, the address it came from, and a command to check it yourself. What we could not read says "could not check": we never guess.
  • A hidden version is good, not proof: the flaw works whether the version is shown or not. Only the server can say.
  • The check keeps nothing: no cookie, and a result stays in memory for an hour, so a second check is instant, then it is gone. But a result page's address names the site you checked (/check/?url=…), and like any page address it is in our server log for 14 days (privacy note).

Who is probing you

How to see who is probing your site

The check above is what anyone can see. Your server log shows who is actually probing you. One of our sites got between 1,085 and 4,148 scanner probes a day this week, from 100 to 150 different addresses. We checked every probe that got a page back: each was the same harmless app page any unknown address gets. Skald reads that log and tells you if anything was handed out.

You can take a first look by hand. On a server running nginx, this lists the addresses that asked for configuration files, Git folders and WordPress's settings file, busiest first:

grep -E '/\.env|/\.git/|wp-config|phpinfo|/\.aws/' /var/log/nginx/access.log \
  | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

What a one-off command can't tell you is whether any of those requests got a real file back, which addresses kept trying for days, or which of them also hammered your login page. That is what Skald does, every day:

  • Is anything exposed? Every request for /.env, /.git/config or a backup, and whether your server may have handed out a real file.
  • Who is scanning you, their attack attempts, and a block list to paste into nginx or Cloudflare.
  • Your stack, every day: which advisories apply to what runs your sites, with what to do.

Free to run on your own server, source-available (Elastic License 2.0). Your data, on your server, and you choose what is kept.

Questions

Questions about php2shell and this check

What is php2shell?

It is the name Cloudflare uses for the two critical PHP flaws fixed on 21 October 2026, CVE-2026-109618 and CVE-2026-109619. They let anyone on the internet run code on a PHP server without signing in. PHP rates them CVSS v4.0 9.2. Cloudflare reports attack traffic already, and says the details leaked before the release.

Does Cloudflare protect me?

It helps if your site is behind Cloudflare: Cloudflare says it deployed firewall rules against php2shell on every plan with its WAF, the Free plan included, from 21 October at 03:02 UTC. Cloudflare itself says customers should patch even with these protections. Update PHP anyway.

Is my PHP version vulnerable to CVE-2026-109618?

It is if it is older than the fixed release of its branch: 8.5.12, 8.4.27, 8.3.36 or 8.2.35. PHP 8.1 and older have no official fixed release at all. Check with php -v on the server, then compare within the same branch.

How can I check the PHP version of a website?

From outside, only if the server says it: the X-Powered-By header often names it, and the check on this page reads it for you. Many servers hide it, which is good practice. Then the sure way is on the server: php -v, WordPress's Site Health screen, or your hosting panel.

Is my WordPress site affected?

WordPress runs on PHP, so its server needs the PHP update whatever WordPress version you run. Updating WordPress itself does not update PHP. Your host or server admin updates PHP.

Does this check test my site for the flaw?

No. It never sends an attack. It reads your home page the way any visitor does and compares what your server shows with the vendors' advisories.

Do you keep the address I type?

The check itself keeps nothing: the result is kept in memory for an hour, so checking again is instant, and then it is dropped, and no cookies are set. But a result page's address names the site you checked (/check/?url=...), and like any page address it is in our web server's log for 14 days, read by our own analytics, Skald. If you download the PDF report, we keep the email you give for it.

Can I check my clients' sites at once?

Yes. The agency mode checks up to 10 sites one at a time, shows a table with each site's summary and worst status, and makes one PDF for all of them with one email. The limit is 10 checks an hour from one address, and the page tells you how many you can still run, and when.

Tell others to check theirs

The fix shipped on 21 October 2026, and every server running PHP needs it. Share the check, never anyone's result: the links below open this page, not a site's findings.

Spread the word: a badge for your README or footer

Tell your visitors and your users that you checked. The badge is the same for everyone: it names no site and shows no result.

php2shell · checked with Skald

Markdown
[![php2shell · checked with Skald](https://skaldanalytics.com/check/badge.svg)](https://skaldanalytics.com/check/)
HTML
<a href="https://skaldanalytics.com/check/"><img src="https://skaldanalytics.com/check/badge.svg" alt="php2shell · checked with Skald" width="194" height="20"></a>

Read the full story in the php2shell guide, or see what Skald's Security section shows from your own log.

Product names and logos belong to their owners; shown only to name what we detected. Logos from Simple Icons (CC0).