Vulnerabilities

Understanding PHP CVEs and Affected Version Ranges

7 min read Updated

In short

A PHP CVE usually lists affected ranges per branch, such as 8.3.0 ≤ v < 8.3.8, with the upper bound being the first fixed release. Match your exact version against the range for your branch, then check the preconditions before judging your real exposure.

The parts of a CVE record

A CVE (Common Vulnerabilities and Exposures) record gives a publicly disclosed vulnerability a unique identifier so that everyone can refer to the same issue. For PHP, the information is spread across several places:

Source What it gives you
CVE.org The official ID and a short description
NVD Enriched data: CVSS scores, CWE category, affected configurations
php-src security advisories The PHP project’s own description, affected and patched versions
PHP ChangeLog Which release fixed which issue, often with the CVE ID
Distribution trackers Status for each packaged version, including backports

The CVE ID

The format is CVE-YEAR-NUMBER. The year is when the ID was reserved, which is not necessarily when the issue was discovered or published. The number has no meaning beyond uniqueness; a five- or six-digit number is not “worse” than a four-digit one.

The description

Read it for three things: the affected component (for example the CGI SAPI, a specific extension or a built-in function), the type of flaw (memory corruption, injection, information disclosure), and the impact (remote code execution, denial of service, data exposure).

The CVSS score

The Common Vulnerability Scoring System, maintained by FIRST, produces a score from 0.0 to 10.0 and a vector string describing how the score was derived. You may see CVSS v3.1 and CVSS v4.0 scores for the same CVE, and they are not directly comparable. Different sources (the PHP project, NVD, a distribution) may also assign different scores.

Range Qualitative rating
0.1 – 3.9 Low
4.0 – 6.9 Medium
7.0 – 8.9 High
9.0 – 10.0 Critical

A score describes technical severity under general assumptions. It does not know your configuration. Treat it as an input to prioritisation, not the final answer.

Reading affected version ranges

PHP vulnerabilities usually affect several branches at once, so advisories list one range per branch. You will see several notations for the same idea.

Notation Meaning
8.3.0 ≤ v < 8.3.8 Every 8.3 release from 8.3.0 up to, but not including, 8.3.8
>= 8.3.0, < 8.3.8 Same as above, written with comparison operators
< 8.2.20 Every version below 8.2.20, usually within the 8.2 branch in context
8.3.0 – 8.3.7 Inclusive list of affected releases; 8.3.8 is the first fixed
<= 8.5.11 Up to and including 8.5.11
“fixed in 8.3.8” Releases before 8.3.8 in that branch are affected

Three rules make these easier to apply.

  1. The exclusive upper bound is the fixed version. In 8.3.0 ≤ v < 8.3.8, the first safe release is 8.3.8.
  2. Ranges are per branch. A fix in 8.3.8 says nothing about 8.2. Look up the fixed version for your own branch.
  3. Compare numerically, not as text. 8.3.10 is newer than 8.3.8, even though “10” sorts before “8” alphabetically. PHP’s version_compare() handles this correctly:
<?php
var_dump(version_compare('8.3.10', '8.3.8', '>=')); // bool(true)

Worked example: CVE-2024-4577

CVE-2024-4577 is an argument injection vulnerability in PHP-CGI on Windows when certain code pages are in use. The fixed releases were 8.1.29, 8.2.20 and 8.3.8, which gives these ranges for the then-supported branches:

Branch Affected First fixed
8.3 8.3.0 ≤ v < 8.3.8 8.3.8
8.2 8.2.0 ≤ v < 8.2.20 8.2.20
8.1 8.1.0 ≤ v < 8.1.29 8.1.29

Branches that were already end of life at the time received no upstream fix, so their entire range is affected with no fixed version.

Worked example: the October 2026 RCEs

On 2026-10-21, PHP released 8.5.12, 8.4.27, 8.3.36 and 8.2.35, fixing two critical remote code execution vulnerabilities, CVE-2026-109618 and CVE-2026-109619, each scored 9.2 under CVSS v4.0. The advisories state that PHP 5.4 through 8.5.11 is affected. Split by branch:

Branch Affected First fixed
8.5 8.5.0 ≤ v < 8.5.12 8.5.12
8.4 8.4.0 ≤ v < 8.4.27 8.4.27
8.3 8.3.0 ≤ v < 8.3.36 8.3.36
8.2 8.2.0 ≤ v < 8.2.35 8.2.35
8.1 and older, back to 5.4 All releases None (end of life)

The summary range “5.4 through 8.5.11” is accurate but easy to misread. It does not mean that 8.4.27 is affected because it is numerically lower than 8.5.11. The per-branch table is what you should match against.

From “affected version” to “actually exposed”

A version inside an affected range is a strong signal, but exposure also depends on conditions that a version number cannot capture.

  • SAPI and platform. CVE-2024-4577 required PHP-CGI on Windows with particular code pages. A Linux server running PHP-FPM with an affected version number was not exposed in the same way.
  • Extensions and functions. Some flaws live in a single extension. If it is not compiled in or loaded, the vulnerable code is absent. php -m lists loaded modules, and php --ri <name> shows details for one.
  • Reachability. Some bugs require an application to pass attacker-controlled data to a specific function. Whether your code does so takes review to determine.
  • Backported fixes. A distribution package may report an affected upstream version while containing the fix. See checking whether a PHP security patch is installed.

The reverse is also true: missing a precondition today does not make an outdated version safe. Configurations change, and a version outside the affected range is the only durable answer.

A practical reading checklist

When a new PHP CVE appears:

  1. Note the CVE ID and the per-branch fixed versions.
  2. Find the range for your branch and compare your exact version numerically.
  3. Read the preconditions: SAPI, OS, extension, configuration.
  4. Check the CVSS score and vector, and which version of CVSS it uses.
  5. If you use distribution packages, check your vendor’s tracker for the same CVE ID.
  6. Decide and record: patch now, patch in the next window, or not applicable with a written reason.

How PatchScope matches ranges

The CVE checker and PHP version checker match the upstream version you provide against the affected ranges recorded for each CVE, and the vulnerability list shows those ranges directly. The methodology page explains the data sources and what the matching does not account for, such as backports and configuration-specific preconditions. For the steps that follow a new advisory, see what to do after a PHP security advisory is published.

Sources

  1. CVE Program
  2. NIST National Vulnerability Database
  3. FIRST: Common Vulnerability Scoring System
  4. php-src Security Advisories on GitHub
  5. PHP 8 ChangeLog