Summary
PatchScope answers two narrow questions: what is publicly known about the security status of a given PHP version, and what a public website reveals about its own configuration when you look at it from the outside. This page documents how the data is assembled, how versions are matched, how each status is decided, what the website checks do, and where the results stop being reliable.
Three principles shape every rule below:
- Accuracy over alarm. We prefer “Insufficient information” or “Potentially affected” to a confident answer we cannot support.
- Never “secure”. No PatchScope result states or implies that a version or a website is secure. A check can only report what it observed.
- Show the source. Every advisory displays where it came from, when it was reviewed and how well it has been verified.
Data sources
The PHP Version Checker and CVE Lookup use a curated, versioned JSON snapshot. It is assembled from:
| Source | Used for |
|---|---|
| php.net supported versions and end-of-life pages | Branch release dates, active support and security support end dates |
| PHP ChangeLog | Fixed versions and the bugs or CVEs each release addresses |
| php-src GitHub security advisories | Advisory descriptions, affected and patched versions |
| CVE records (CVE.org) and NVD | CVE identifiers, descriptions, CVSS scores and references |
| Reputable vendor and distribution trackers | Supplementary detail when a primary source was unavailable |
The dataset covers vulnerabilities in the PHP engine and its bundled extensions (php-src). It does not cover WordPress, frameworks, Composer packages, PECL extensions, or applications written in PHP.
Verification levels
Every advisory record carries:
- Source URLs for each fact it contains.
- A reviewed date, the day the record was last checked against its sources.
- A verification level:
primary(confirmed against an official PHP source) orsecondary – pending primary verification(based on CVE/NVD or a vendor tracker while an official PHP confirmation is not yet available).
The interface shows the verification level next to each advisory. Records from 2026 in particular may rely on secondary sources until they are verified.
CVSS scores
CVSS scores from different sources can conflict. The PHP project, NVD and distribution vendors sometimes score the same issue differently because they assume different deployment contexts. PatchScope shows the source of each score rather than picking one silently. Treat a score as one input to prioritization, not as a verdict on your own exposure.
Update process and freshness
The snapshot is updated by a scripted, reviewed process. Changes pass through a validation script in the repository that checks schema, version ranges, date consistency and source fields before publication. A scheduled update job is planned.
The snapshot carries a coverage through date. If the data you are viewing is more than 45 days older than the current date, the checker displays a warning, because newer releases and advisories may be missing.
Data model
Branch lifecycle
Each PHP branch (for example 8.3) records its initial release date, the end of active support and the end of security support. The branch status is derived from those dates and the current date:
| Status | Meaning |
|---|---|
| Active | Receives bug fixes and security fixes |
| Security fixes only | Receives security fixes only, on an as-needed basis |
| End of life | Receives no further fixes from the PHP project |
| Pre-release | Not yet generally available (alpha, beta, RC) |
| Unknown | The dataset has no lifecycle record for this branch |
Advisory records
Each advisory lists, per branch:
- Affected ranges: the versions within that branch that the advisory states are vulnerable.
- Fixed versions: the first release in each branch containing the fix.
For branches the advisory does not list, a policy field records how older branches should be treated:
- affected-no-fix: older branches are understood to be affected, but no fix was released because they were already unsupported.
- not-assessed: the advisory does not say whether older branches are affected.
- not-affected: older branches are known not to contain the vulnerable code.
Branches released on or after the advisory date are considered to include the fix.
Version parsing
The checker accepts:
- A full version:
8.3.10 - A prefixed version:
PHP 8.3.10 - Pre-releases:
8.4.0RC1,8.4.0beta2 - Distribution build strings:
8.1.2-1ubuntu2.20,7.4.33-1+deb11u5 - A branch only:
8.3
Leading and trailing text is trimmed. A distribution suffix is kept and flagged, because it changes how the result must be interpreted (see below). Input that cannot be parsed as a PHP version is rejected with an explanation rather than guessed at.
Matching rules and statuses
For each advisory, the checker assigns one of four statuses.
Affected
The version falls inside a range that the advisory explicitly lists as affected.
Potentially affected
The version may be affected, but the data cannot confirm it. Typical causes:
- The branch is unsupported and the advisory did not assess it (
not-assessedpolicy). - The input is a distribution build string such as
8.1.2-1ubuntu2.20. Distribution packages often backport security fixes without changing the upstream version number, so the upstream version alone does not tell us whether the fix is present.
Not affected / fixed
The version is at or above the fixed version for its branch, or the branch is outside the affected scope according to the advisory.
Insufficient information
The checker cannot reach a defensible answer. Typical causes:
- Branch-only input such as
8.3, where the patch level decides the outcome. - A version newer than the dataset’s coverage.
- An unreleased branch.
- Gaps in the advisory data for that branch.
Overall verdict
The overall verdict combines the advisory statuses with branch support:
- If any advisory is Affected, the verdict is affected.
- Otherwise, if any is Potentially affected or Insufficient information, the verdict reflects that uncertainty.
- An End of life branch never receives a clean result. Even when no listed advisory matches, the verdict states that the branch no longer receives security fixes, and that future vulnerabilities will not be patched upstream.
- A clean result for a supported branch means only that no advisory in the current dataset matches the version entered. It is not a statement that the version is secure.
Upgrade recommendations
Recommendations follow a fixed order:
- Latest patch in your branch. If your branch is still supported, the first step is the latest patch release of that branch. This is usually the lowest-risk change.
- Newest stable branch. The checker also names the newest stable branch as the longer-term target.
- For end-of-life branches, the checker recommends the oldest supported branch that still has at least 12 months of security support left. This balances compatibility (a smaller jump) against having to upgrade again soon.
Recommendations are based on lifecycle data only. They do not account for application compatibility, which you must test separately.
Website security checks
The Website Security Checker runs server-side in a Cloudflare Pages Function. It performs passive checks against a public website that you own or have permission to test.
Checks and thresholds
| Check | What it looks at | How it is classified |
|---|---|---|
| HTTPS availability | Whether the site responds over HTTPS with a valid connection | No HTTPS is an issue |
| HTTP to HTTPS redirect | Whether plain HTTP redirects to HTTPS | No redirect is an issue |
| Strict-Transport-Security | Presence and max-age of HSTS on HTTPS responses |
Missing on HTTPS is an issue; max-age under 180 days is a potential issue |
| Content-Security-Policy | Presence of a CSP header | Missing is a potential issue |
| X-Content-Type-Options | nosniff value |
Missing or incorrect is a potential issue |
| X-Frame-Options / frame-ancestors | Clickjacking protection via either header or CSP directive | Neither present is a potential issue |
| Referrer-Policy | Presence and value | Missing is a potential issue |
| Permissions-Policy | Presence | Missing is a potential issue |
| PHP version disclosure | Version in X-Powered-By or Server |
Disclosure is reported; the disclosed version is cross-checked against lifecycle data, and an end-of-life version is an issue |
| Server software disclosure | Version numbers in Server and similar headers |
Version disclosure is a potential issue |
| Cookie flags | Secure, HttpOnly, SameSite on cookies set by the response |
Missing flags are reported per cookie name |
| security.txt | Presence of /.well-known/security.txt |
Missing is a potential issue |
| Sensitive paths | A fixed list of well-known paths (below) | Confirmed exposure is an issue |
Cookie checks record only cookie names and attributes, never cookie values.
Sensitive path checks
The scanner sends a single GET request to each of these paths:
/.git/HEAD, /.env, /phpinfo.php, /info.php, /wp-config.php.bak, /wp-config.php~, /wp-content/debug.log, /server-status, /.DS_Store
A 200 OK response alone is not treated as exposure. Many sites return a normal page for any path (“soft 404”). An exposure is reported only when the response body matches a content signature for that file type, for example the ref: line of a Git HEAD file or the structure of a phpinfo page. Response bodies are inspected in memory, up to 64 KB, and are never stored or returned. Results show only status codes and header values.
Result categories
- Issue detected: the check found a clear problem.
- Potential issue: something worth reviewing, which may be acceptable in your context.
- No issue detected by this check: this specific check found nothing. It does not mean the site is secure.
- Unable to determine: the check could not complete, for example because of a timeout, a block or an unexpected response.
What the scanner does not do
It does not exploit vulnerabilities, brute-force or guess credentials, crawl the site, fuzz parameters, scan ports, test forms or send POST requests to the target.
SSRF safeguards
Because the scanner fetches user-supplied URLs from our infrastructure, it applies strict request controls:
- Only
httpandhttpson default ports. - No credentials in URLs.
- IP address literals are rejected.
- Internal and special-use hostnames are rejected (for example
localhost,.local,.internal). - DNS is resolved via DNS-over-HTTPS, and every resolved address must be public.
- Each redirect hop is re-validated against the same rules, up to 5 redirects.
- A 6-second timeout per request and a total budget of about 25 seconds per scan.
- A cap on the number of requests per scan, and rate limiting per client.
User agent
Requests are sent with the user agent:
PatchScopeBot/1.0 (+https://patchscope.evoa.one/methodology)
Site owners who do not want their site checked can block this user agent.
Known limitations
- Backported fixes. A PHP version number alone cannot prove whether a hosting provider or Linux distribution such as Debian, Ubuntu or RHEL has backported a security fix. A distribution package reporting
8.1.2may contain fixes from much later upstream releases. Check your distribution’s security tracker or package changelog for a definitive answer. - Header-based checks see only what the site exposes. Hiding
X-Powered-Bydoes not upgrade PHP, and a missing header does not tell us which version runs. - CDNs and WAFs can add, remove or rewrite headers, so results may describe the edge rather than the origin server.
- Soft 404 handling relies on signatures. Unusual server responses may still produce an “Unable to determine” result.
- External view only. An external scan cannot see server configuration, installed plugins, file permissions or application code.
- Partial advisory coverage. The dataset is curated, not exhaustive. Absence of a CVE from our dataset is not evidence that it does not exist; CVE Lookup links to CVE.org and NVD when a search finds nothing.
- Recent records. Advisories from 2026 may rely on secondary sources until primary verification is complete. Their verification level is shown.
Reporting errors
If you find an incorrect version range, a missing advisory, a wrong date or a misclassified website check, please tell us. You can open an issue in the GitHub repository or use the details on the contact page. Include the advisory or CVE ID, the version or URL you tested, what PatchScope showed, what you expected, and a link to a source supporting the correction.
Security vulnerabilities in PatchScope itself should not be reported publicly. See the security policy.