---
title: Free PHP Version and Software Exposure Checkers
description: Two new free tools: check the PHP version of any website against php2shell (CVE-2026-109618, CVE-2026-109619), end of life and known CVEs, and see every software version a site reveals, graded A+ to F with the fix.
canonical: https://watchfor.io/blog/free-php-version-checker-and-software-exposure-checker
---

# Free PHP Version and Software Exposure Checkers

2026-10-22 · WatchFor Team · Security · security, php, vulnerabilities, http, web

Two new free tools: check the PHP version of any website against php2shell (CVE-2026-109618, CVE-2026-109619), end of life and known CVEs, and see every software version a site reveals, graded A+ to F with the fix.

Two free tools are live on WatchFor today:

- The [PHP Version Checker](/php-version-checker) reads the PHP version a
  website announces and grades it A+ to F against **php2shell**
  (CVE-2026-109618, CVE-2026-109619), the other known CVEs, CISA's list of
  exploited bugs and PHP's end-of-life calendar.
- The [Software Exposure Checker](/software-exposure-checker) reads
  everything a page gives away (web server, PHP, CMS, JavaScript libraries)
  and grades the whole stack the same way: what you reveal, what is outdated
  or past end of life, and which known CVEs may apply.

Both see your site the way a scanner does, from the outside, with ordinary
GET requests. No signup, no agent to install, nothing exploit-like. This
post shows what each tool answers on real runs, how the grades are worked
out, and what they can't tell you.

## Check the PHP version of a website

php2shell is an unauthenticated remote code execution bug in PHP itself,
scored CVSS 9.2. The PHP project announced it on Oct 20, 2026 and fixed it the
next day in **8.5.12, 8.4.27, 8.3.36 and 8.2.35**. A public proof of concept
exists, and 8.1 and older are past end of life, so they got no fix. The
question every PHP team had that morning was "which of our sites still run an
affected build?" The PHP Version Checker answers it for one hostname in a few
seconds.

Enter a URL and press **Check PHP version**. A probe near you fetches the page
with a plain GET, follows redirects and reads the response headers:

- `X-Powered-By: PHP/8.3.14`, which PHP adds itself while `expose_php` is on;
- `PHP/8.2.20` inside the `Server` header, which Apache with mod_php can send;
- a `PHPSESSID` cookie, which proves PHP runs even when the version is hidden.

If the page shows no version, the checker makes exactly one more GET, to
`/index.php` on the site it landed on, because PHP often announces itself on a
PHP-served path when the home page is cached. That is the whole conversation:
two plain requests at most.

### A vulnerable PHP version: 8.3.14 gets an F

We point the checker at our own demo endpoint,
`https://watchfor.io/demo/php/8.3.14`, which answers with
`X-Powered-By: PHP/8.3.14` and nothing else (no PHP runs there; it only sends
the header). The result:

![PHP Version Checker result for a server announcing PHP 8.3.14: grade F, php2shell affected and fixed in 8.3.36, the PHP 8.3 branch on security fixes only with 435 days left, 22 releases behind 8.3.36, and the exact upgrade to run](/blog/free-php-version-checker-and-software-exposure-checker-php-affected.52d2ad82.webp)

Reading it top to bottom:

- **Fix first** names the finding that set the grade: php2shell.
- **What we saw** is the evidence, the exact header line and every request
  with its status code, so you can compare it with your server.
- **php2shell** says *Affected* and names **8.3.36** as the fix for this
  branch, with the first fixed release of every other branch.
- **PHP 8.3 support**: the branch gets security fixes only, until
  Dec 31, 2027, and 8.3.14 is **22 releases behind** 8.3.36.
- **What to run**: install 8.3.36 now, then plan the move to 8.5 (or 8.4, the
  smaller step).

Below the cards, the checker lists the 22 other CVEs whose affected range
includes 8.3.14 (2 critical, 6 high, 12 medium, 2 low), worst first, each
linked to NVD, and every finding with the grade it caps and its fix. The
**Share** button gives you a link to send to whoever owns the server.

### A patched PHP version: 8.4.27 gets an A+

The same check against `https://watchfor.io/demo/php/8.4.27`, the latest
release of a branch with active support:

![PHP Version Checker result for PHP 8.4.27: grade A+, php2shell not affected because 8.4.27 includes the fix, active support until Dec 31, 2026 and security fixes until Dec 31, 2028, on the latest 8.4 release with no other known CVE](/blog/free-php-version-checker-and-software-exposure-checker-php-patched.461230c0.webp)

Not affected by php2shell, up to date, no other known CVE: **A+**. The one
note left is information only. The version is still visible in
`X-Powered-By`, and the card shows the `php.ini`, nginx, Apache, Caddy and
Cloudflare config that hides it. Hiding the version is good practice, but it
never changes the grade, because it changes what a stranger sees, not what
runs.

### A site that shows no PHP: no grade

`github.com` sends no PHP version, no PHP session cookie, and `/index.php`
answers 404:

![PHP Version Checker result for github.com: not graded, no sign of PHP in the response headers, GET https://github.com answered 200 and GET https://github.com/index.php answered 404, with the php2shell fixed-release table for comparison](/blog/free-php-version-checker-and-software-exposure-checker-php-hidden.3dfa3298.webp)

**Not graded** is the honest answer. A hidden version is never a failing
grade. When your own server hides it (good), the result tells you to check it
on the box with `php -v` and compare it with the fixed releases it lists.

## Is my PHP version vulnerable? How the grade works

Every WatchFor grade starts at A+, and each finding can only lower it to a cap.
The worst cap wins, and the result names it:

| Cap | PHP Version Checker rule |
| --- | --- |
| **F** | Affected by php2shell: below 8.2.35, 8.3.0–8.3.35, 8.4.0–8.4.26 or 8.5.0–8.5.11 |
| **F** | A CVE in CISA's Known Exploited Vulnerabilities catalog, or any CVE scored 9.0 or higher |
| **F** | The branch reached end of life more than two years ago |
| **D** | The branch reached end of life within the last two years |
| **C** | A high-severity CVE (CVSS 7.0–8.9) |
| **C** | A distribution build that would otherwise be D or F (see below) |
| **B** | A medium-severity CVE, behind the latest release of a security-only branch, or a branch that loses support within 180 days |
| **A** | Behind the latest release of an actively supported branch, or on the latest release of a security-only branch |

The full rule table sits under the tool and on
[WatchFor Grades](/grades#php-version), with the rubric version
(`php-2026.10`), so a grade can always be traced back to its rules.

### PHP end of life: 8.2, 8.1 and 7.4

Every PHP branch gets two years of active support and two years of security
fixes, then nothing. On the day this post went out (Oct 22, 2026):

- **PHP 8.2 end of life is Dec 31, 2026**, 70 days away. 8.2.35 fixes
  php2shell, but after that date nothing gets fixed in 8.2. That is why a
  branch ending within six months caps at B: it is roughly how long a careful
  upgrade of a large application takes.
- **PHP 8.1** reached end of life on Dec 31, 2025 and **PHP 7.4** on
  Nov 28, 2022. Neither got a php2shell fix, so both grade F.

The branch table on the [PHP Version Checker](/php-version-checker) page lists
every branch since 7.0 with its dates and the days it has left, computed from
the release data rather than written by hand.

### Debian, Ubuntu and Red Hat builds say "verify", not F

Distributions backport security fixes into their own packages and keep the
upstream version number. Ubuntu 22.04's PHP says `8.1.2` for its whole life,
patched or not. So when the header carries a distribution suffix such as
`-1ubuntu2.19`, `+deb12u1` or `(Debian)`, the checker never fails the build on
its number alone: a verdict that would be D or F is capped at **C**, php2shell
shows **verify**, and the card links the vendor's tracker for each CVE. The
package changelog is the only place that knows; the
[php2shell guide](/blog/php2shell-check-if-your-site-is-vulnerable) has the
`apt` and `rpm` commands to check it.

## Website vulnerability checker for the whole stack

PHP is one line of what a response can say. `Server: Apache/2.4.29 (Ubuntu)`
names the web server and the OS, a generator tag names the CMS to the patch
release, a script URL like `/ajax/libs/jquery/1.12.4/` names a front-end
library. None of it is a vulnerability by itself. All of it tells a stranger
which known bugs are worth trying first.

The Software Exposure Checker reads those signals from **one plain GET**: the
response headers in full and the first **256 KB** of the HTML. It never
downloads the scripts the page loads, never guesses paths and refuses private
addresses. From that one response it finds:

- **headers**: `Server` with every module in it (Apache, OpenSSL, PHP…),
  `X-Powered-By`, `X-AspNet-Version`, `X-Generator`, `Via`, the Drupal and
  Varnish headers and a few product-specific ones;
- **HTML**: the generator tag, WordPress core asset versions (`?ver=` on its
  own files), Apache, nginx and Tomcat error-page signatures, and front-end
  libraries recognised from their script and stylesheet URLs, using
  retire.js's patterns plus the versioned paths of the public CDNs.

Each signal keeps its evidence and a confidence: **exact** (the software
states it), **distribution build** (a Debian, Ubuntu, Red Hat or SUSE
package) or **inferred** (read from something not meant as a version
statement, such as `?ver=`).

### An outdated stack: five versions, grade F

Our demo page `https://watchfor.io/demo/exposure/outdated` answers like an old
WordPress site. Nothing it names is installed, and its scripts never run:

![Software Exposure Checker result for the outdated-stack demo: grade F, 5 versions seen, and a What you reveal table listing PHP 7.4.33 in X-Powered-By, WordPress 5.8 in the meta generator tag and a core asset URL, Bootstrap 3.3.7 and jQuery 1.12.4 from CDN URLs, and Apache 2.4.29 on Ubuntu in a server signature](/blog/free-php-version-checker-and-software-exposure-checker-exposure-reveal.57764316.webp)

The table lists nine signals. Two of them are honest about our own
infrastructure: in production the demo sits behind our CDN and a reverse
proxy, so `Server: cloudflare` and `Via: 1.1 Caddy` show up too, as products
with no version, which are listed but not graded. The five versions:

- **PHP 7.4.33**: end of life for 1,424 days, affected by php2shell. That
  alone is an **F**, the same verdict the PHP Version Checker gives, because
  the PHP component is graded by the PHP Version Checker's own rubric.
- **WordPress 5.8**: 18 releases behind 5.8.18, and in the range of a CVE
  that CISA lists as exploited.
- **Apache 2.4.29 (Ubuntu)**: 40 releases behind 2.4.69 by number and in the
  range of three known-exploited CVEs. It is an Ubuntu package, so the card
  says **verify**, not "affected".
- **jQuery 1.12.4**: end of life since May 20, 2016, and affected by
  CVE-2020-11023, which is in CISA's Known Exploited Vulnerabilities catalog.
- **Bootstrap 3.3.7**: end of life since Jul 24, 2019, with seven
  medium-severity CVEs.

Every finding then lands in **What to fix**, worst first, each with the cap it
sets and the upgrade or config change:

![Software Exposure Checker What to fix list for the outdated demo, worst first: PHP 7.4.33 affected by php2shell (max F), WordPress 5.8 with a known-exploited CVE (max F), Bootstrap 3.x and jQuery 1.x past end of life (max C), jQuery 1.12.4 with a known-exploited CVE (max C), Apache 2.4.29 with three known-exploited CVEs to verify with Ubuntu (max C), and the outdated releases and three revealed versions (max B)](/blog/free-php-version-checker-and-software-exposure-checker-exposure-fix.69fa8427.webp)

Further down, each version disclosure comes with a ready-to-paste snippet:
`expose_php = Off`, WordPress's `remove_action( 'wp_head', 'wp_generator' )`,
a filter that drops `?ver=` from core assets, and `ServerSignature Off` for
Apache.

### A site that reveals nothing: A+

The same check against `github.com`:

![Software Exposure Checker result for github.com: grade A+, zero versions seen, one GET answered 200, the first 256 KB of HTML read and nothing else fetched, with notes that scripts further down the page were not checked and that the checker can only see what the page shows](/blog/free-php-version-checker-and-software-exposure-checker-exposure-clean.29342853.webp)

Nothing in the headers or the HTML names a version: **A+**. Two notes come
with it, and both are there on purpose. GitHub's HTML is longer than 256 KB, so
the result says the rest wasn't checked. And an A+ only means the page says
nothing; it says nothing about software that doesn't announce itself, so
check patch levels on the servers too.

## How the exposure grade works

The rubric (`exposure-2026.10`) follows the same rules as every WatchFor
grade, with caps built for a tool that runs against sites it doesn't control,
where a version number is a lead, never proof:

| Cap | Software Exposure Checker rule |
| --- | --- |
| **F** | An exact server, runtime or CMS version in the range of a known-exploited CVE or one scored 9.0+, a long-lifecycle product (PHP, OpenSSL, Apache httpd, Tomcat, IIS, Drupal, Joomla) more than two years past end of life, or PHP graded F by the PHP Version Checker |
| **D** | Server, runtime or CMS software past end of life (nginx at worst D), a high-severity CVE, or an inferred version that would otherwise be F |
| **C** | A distribution build that would otherwise be D or F, or a front-end library with a known-exploited, critical or high-severity CVE, or past end of life |
| **B** | Behind the latest patch release, support ending within 180 days, a medium-severity CVE, or three or more distinct versions revealed |
| **A** | Any header or HTML signal names a version, even a current one |

Three caps are worth spelling out:

- **jQuery vulnerability check, capped at C.** Whether a jQuery or Bootstrap
  CVE is reachable depends on how your page uses the library, which can't be
  seen from outside. A front-end library never sets an F; the result says
  "may be affected". Upgrading is usually still cheaper than proving you are
  safe.
- **Disclosure alone is mild.** Any version shown caps at A, and three or
  more *distinct* versions at B: the same Apache in the `Server` header and an
  error page counts once. Front-end library URLs don't count (nobody hides
  those), and a major version alone such as `Apache/2` or `Drupal 10` is only
  a note.
- **Inferred versions are never failed outright.** WordPress's `?ver=` or
  nginx under OpenResty stop at D.

The full table is under the tool and on
[WatchFor Grades](/grades#software-exposure).

## Where the data comes from

Both checkers grade against the same data, refreshed every 6 hours:

- **php.net** for PHP's latest release per branch;
- **endoflife.date** for release branches and support dates;
- **NVD** for CVEs in PHP, nginx, Apache httpd, OpenSSL, Tomcat, WordPress,
  Drupal and Joomla;
- **retire.js** for front-end library advisories and the URL patterns that
  recognise those libraries;
- **CISA KEV** to flag every CVE that is exploited in the wild.

Every result ends with "Release and CVE data as of …". If a feed hasn't
loaded or the data is stale, the result says so instead of grading quietly
from old numbers.

## What these checkers don't do

A free CVE checker that reads version numbers is useful exactly as far as
version numbers go. So, plainly:

- **No exploits, no probing.** Ordinary GET requests from a signed WatchForBot
  probe, the same requests a browser sends. Nothing that could trigger
  php2shell or any other bug.
- **No logins, no paths.** They read what any anonymous visitor receives on
  the page you enter, nothing behind it.
- **A hidden version stays hidden.** If your server hides it, the checker
  can't grade it, and says so.
- **A version is a lead, not proof.** Distribution builds may carry the fix
  under the old number; a library CVE may not be reachable. The result says
  "verify" and "may be affected" where that is the honest answer.
- **A bot challenge isn't your site.** When a CDN challenge or WAF block page
  answers instead of the site, the exposure check is not graded.

Only check sites you own or are allowed to test: the result names weaknesses,
and it is meant for the people who can fix them.

## From a terminal, the API or an AI agent

Both checks run in the [curl terminal](/terminal), no browser needed:

```bash
curl https://watchfor.io/php/example.com
curl https://watchfor.io/exposure/example.com
```

The same PHP check as above, from a terminal:

![curl https://watchfor.io/php/watchfor.io/demo/php/8.3.14 in a terminal: grade F, PHP 8.3.14, php2shell affected and fixed in 8.3.36, the 8.3 branch on security fixes only and 22 releases behind, 22 other known CVEs, what caps the grade at F, and the upgrade to run](/blog/free-php-version-checker-and-software-exposure-checker-terminal.b15c068d.webp)

For scripts and agents, both are live diagnostics in the REST API, the MCP
server and A2A, with the same grade in the response: the API docs cover the
[PHP Version Checker diagnostic](/docs/api/diagnostics#php-version-checker)
and the
[Software Exposure Checker diagnostic](/docs/api/diagnostics#software-exposure-checker)
(slugs `php-version-checker` and `software-exposure-checker`).
More commands are in
[WatchFor in your terminal](/blog/watchfor-in-your-terminal).

## After the check: patch, restart, hide, keep watching

The order matters:

1. **Patch.** Install the fixed release of your branch, or move off an
   end-of-life one.
2. **Restart.** A new package on disk changes nothing until PHP-FPM, Apache
   or nginx restarts.
3. **Hide.** Turn version disclosure off so the next scanner learns less.
4. **Check again** from outside, because a forgotten pool member or a proxy
   can still answer with the old headers.

The two guides go deeper:
[php2shell: how to check if your site is vulnerable](/blog/php2shell-check-if-your-site-is-vulnerable)
covers patching on Debian, Ubuntu, Red Hat and Docker, and
[What your server headers reveal](/blog/what-your-server-headers-reveal)
has the config that hides versions on nginx, Apache, IIS, PHP, WordPress,
Express and Cloudflare.

Version disclosure tends to come back after an upgrade or a new server. An
[API monitor](/api-monitoring) on your home page with the header assertions
`X-Powered-By` **does not exist** and `Server` **matches regex** `^[^0-9]*$`
alerts the day it does. [Page integrity monitoring](/page-integrity-monitoring)
alerts when a page starts loading a script from a new source, which is what
a compromised PHP site typically looks like from the outside.

## FAQ

### How do I check the PHP version of a website?

Enter the URL in the [PHP Version Checker](/php-version-checker). It reads the
version the server announces in `X-Powered-By` or `Server`, grades it against
php2shell, known CVEs and end of life, and names the release to install. On
the server itself, `php -v` shows the command-line PHP, which can differ from
the PHP-FPM or mod_php that serves requests.

### Is my PHP version vulnerable to php2shell?

Every release below 8.2.35, and 8.3.0–8.3.35, 8.4.0–8.4.26 and 8.5.0–8.5.11,
is affected by CVE-2026-109618 and CVE-2026-109619. PHP 8.1 and older got no
fix. A distribution build in that range may be patched: check your vendor's
tracker.

### When does PHP 8.2 reach end of life?

PHP 8.2 gets security fixes until Dec 31, 2026. After that nothing is fixed
in it, so install 8.2.35 now and plan the move to 8.4 or 8.5.

### Is this a website vulnerability scanner?

It is a passive check of what your site reveals, matched against known CVEs
and end-of-life dates. It doesn't send attacks or test for misconfigurations,
and it can't see software that hides its version. Treat a result as a list of
leads to verify, not as a penetration test.

### Why does my Ubuntu server get a C with "verify" instead of an F?

Ubuntu, Debian, Red Hat and SUSE backport fixes without changing the version
number, so the number alone can't prove the server is vulnerable. The checker
caps such builds at C and links the vendor's tracker for each CVE. Until you
have checked the package changelog, treat it as affected.

### Does hiding X-Powered-By or the Server version fix anything?

No. It stops casual fingerprinting, and you should do it, but the software
underneath is unchanged and attackers also try exploits blind. Patch first,
hide second. That is why disclosure alone caps at A.

### Can it check my jQuery version for vulnerabilities?

Yes, when the page loads jQuery from a versioned URL (a CDN path or a file
name such as `jquery-1.12.4.min.js`). The Software Exposure Checker matches
the version against retire.js advisories and CISA's exploited list, and caps
the grade at C, because whether the bug is reachable depends on how your page
uses jQuery.

### Are the checkers free?

Yes. Both run without an account, on the web and in the curl terminal, with
an hourly limit per visitor. A free account lets you pick the probe location;
the REST API and MCP server run the same checks with an API key.

---

Canonical page: https://watchfor.io/blog/free-php-version-checker-and-software-exposure-checker · All articles: https://watchfor.io/blog/all.md · Site guide: https://watchfor.io/llms.txt
