Most internet-facing PHP runs on a branch the PHP project no longer patches, and PHP2Shell showed what that costs when a critical runtime flaw lands. PHP 8.1 reached end of life on 31 December 2025 and PHP 8.2 follows on 31 December 2026, while scans cited by Recorded Future in October 2026 found the large majority of version-disclosing PHP services on unsupported branches. This guide explains how the PHP lifecycle works, what distribution backports and commercial long-term support really give you, how to find every PHP runtime across an estate (including the ones the version string lies about), and how to plan and test the upgrade. It is for vulnerability management, platform and web hosting teams. General PHP and WordPress hardening is in the PHP and WordPress Security Guide, and the operating system side of end of life is in the Operating System End of Life and Extended Support Guide. Dates were checked on php.net and vendor lifecycle pages on 2 November 2026.
Key takeaways
- Each PHP branch gets four years, then nothing. Two years of active support, two years of security fixes only, then end of life. PHP 8.2 leaves security support on 31 December 2026; 8.3 on 31 December 2027.
- The upstream version string is not the patch state. Ubuntu 24.04 fixed PHP2Shell in a package that still reports PHP 8.3.6, and Debian, Red Hat and others backport in the same way. Check the vendor's security tracker, not
php -valone. - Backports and extended support buy time, not safety. They depend on the vendor choosing to fix each flaw, often cover only what is in their repositories, and sometimes need a paid subscription. Plan the upgrade on the same day you buy the extension.
- Discovery has to cover every way PHP arrives. Operating system packages, control panel builds, containers, vendor appliances, developer stacks and managed hosting all carry their own PHP, and each needs an owner.
- Upgrade in tested steps. Scan code for compatibility, fix deprecations on the current branch, move one branch at a time where the code is old, and roll out in rings with a fast rollback that does not return you to an unpatched build.
How the PHP lifecycle works
The PHP project's supported versions page defines three states. During active support, reported bugs and security issues are fixed in regular point releases. During security fixes only, releases are made for critical security issues on an as-needed basis, so there may be several or none. At end of life the branch receives nothing, and php.net advises users to upgrade as soon as possible. Each branch is fully supported for two years from its first stable release and then receives two more years of security-only support.
| Branch | Initial release | Active support until | Security support until | Status on 2 November 2026 |
|---|---|---|---|---|
| 8.5 | 20 Nov 2025 | 31 Dec 2027 | 31 Dec 2029 | Active support |
| 8.4 | 21 Nov 2024 | 31 Dec 2026 | 31 Dec 2028 | Active support |
| 8.3 | 23 Nov 2023 | 31 Dec 2025 | 31 Dec 2027 | Security fixes only |
| 8.2 | 8 Dec 2022 | 31 Dec 2024 | 31 Dec 2026 | Security fixes only, ends in under two months |
| 8.1 | End of life 31 Dec 2025, last release 8.1.34 | Unsupported | ||
| 8.0 | End of life 26 Nov 2023, last release 8.0.30 | Unsupported | ||
| 7.4 | End of life 28 Nov 2022, last release 7.4.33 | Unsupported | ||
| 7.3 and older | 7.3 ended 6 Dec 2021; 7.2 30 Nov 2020; 7.0 10 Jan 2019; 5.6 31 Dec 2018 | Unsupported | ||
PHP 8.6 is in release candidate testing (RC5 planned for 5 November 2026 according to php.net) and is not for production. The practical rule from these dates: a branch you deploy today should be 8.4 or 8.5, which leaves at least two years of security support, and anything on 8.2 needs an upgrade scheduled now.
Why unsupported PHP is a real risk, with evidence
- Runtime flaws hit every application: PHP2Shell (CVE-2026-109618 and CVE-2026-109619) sits in the interpreter, not in a framework, and CISA added both CVEs to its Known Exploited Vulnerabilities catalogue on 26 October 2026. The PHP project released fixes only for 8.2 to 8.5 and published minimal source backports for 7.4, 8.0 and 8.1; Security Affairs reported that 5.4 to 7.3 have no fix. See the PHP2Shell guide.
- The exposed population is mostly unsupported: Recorded Future cites Modat data showing about 79 percent of internet-facing PHP services with a readable version on unsupported branches, with PHP 7.4 alone accounting for 878,761 services, and VirusTotal data showing about 758,000 of roughly 1.1 million version-disclosing IP addresses on branches 5.4 to 8.1. These are vendor figures based on version banners, not confirmed vulnerable hosts.
- Old PHP flaws stay exploited for years: the CISA KEV catalogue lists CVE-2012-1823 (PHP-CGI query string, added 2022), CVE-2019-11043 (PHP-FPM, added 2022, known ransomware use) and CVE-2024-4577 (PHP-CGI on Windows, added 2024, known ransomware use). Unsupported hosts collect these and never shed them.
- The application stack moves on: WordPress recommends PHP 8.3 or greater and warns that the older versions it still runs on, down to 7.4, have reached end of life and may expose a site to vulnerabilities. Libraries drop old branches too, so a frozen runtime also freezes dependency updates.
The live tracker of the campaign activity is the PHP2Shell campaign tracker.
Backports, distribution support and commercial long-term support
"Unsupported by php.net" and "unpatched" are not the same thing. Several kinds of supplier keep shipping fixes for branches the PHP project has retired, each with different scope.
| Source of PHP | How fixes arrive | Example from the PHP2Shell fixes | Watch out for |
|---|---|---|---|
| Upstream php.net builds | Point releases on supported branches only | 8.5.12, 8.4.27, 8.3.36, 8.2.35 on 21 October 2026; Windows -1 rebuilds on 26 October | Nothing for 8.1 and older apart from minimal source backports the project chose to publish |
| Ubuntu | Security fixes backported into the release's own PHP package; Main covered for 5 years standard, longer with Ubuntu Pro (ESM) | 22.04 php8.1 fixed in 8.1.2-1ubuntu2.28; 24.04 php8.3 in 8.3.6-0ubuntu0.24.04.13; 20.04 php7.4 fixed only under Ubuntu Pro | Version string stays at the original upstream number; older releases need a Pro subscription to receive the fix |
| Debian | Security team (DSA) for stable, LTS team (DLA) for older releases | bookworm php8.2 fixed in 8.2.35-1~deb12u1 (DLA-4848-1); trixie php8.4 in 8.4.27-1~deb13u1 (DSA-6574-1) | LTS covers selected packages for a fixed period; check the tracker per CVE |
| Red Hat Enterprise Linux | PHP shipped as Application Streams with their own retirement dates | RHEL 9 PHP 8.2 and 8.3 streams supported to May 2029; RHEL 9 PHP 8.1 stream retired May 2025 | Red Hat states Application Streams have no EUS or ELS extension and retired streams get no errata |
| Hosting control panel and LTS vendors | Vendor-built PHP packages for many branches side by side | Security Affairs reported cPanel EasyApache, CloudLinux, TuxCare and Plesk shipping their own builds | Each build is a separate binary to patch and restart; confirm the vendor's advisory, not only the panel's version selector |
| Containers and PaaS | New base image or platform runtime | Rebuild from a patched image tag | Old tags in registries can be redeployed; platforms retire runtimes on their own schedule |
Choosing between upgrade, backport and extended support
- Upgrade to a supported branch when the application is maintained, its dependencies support the target branch, and you can test it. This is the default and the only option that also restores normal bug fixes and library updates.
- Use the distribution's backported package when the host runs a supported OS release and you need the OS's PHP for stability. It is safe for as long as the OS release and its PHP stream are supported, so record that end date.
- Buy commercial extended support only as a bridge for an application that cannot move yet, with a named retirement date. Confirm in writing which CVEs the supplier commits to fix, how fast, and for which SAPIs and extensions.
- Isolate or retire anything nobody can upgrade or patch: remove internet exposure, put it behind authentication and strict request limits, and set a decommission date. The Edge Device End of Life Replacement Playbook uses the same decision logic for appliances.
Small organisations with a handful of sites usually do best moving to a managed host that runs current branches and upgrading the site, rather than buying extended support. Large estates need all four options at once and a register showing which one applies to each runtime.
Finding every PHP runtime across an estate
Inventory is where most programmes fail. Each route below finds runtimes the others miss.
- Package managers on servers. Query installed PHP packages (for example
dpkg -l 'php*'orrpm -qa 'php*') through configuration management or your vulnerability scanner's authenticated checks. Record the package name and full package version, not just the branch. - The web SAPI, not only the CLI. The command-line
phpand the PHP used by Apache, PHP-FPM or a control panel can be different builds. Enumerate FPM pools and Apache modules, and on panel servers list every PHP build the panel offers and which sites use each. - Control panel version selectors. cPanel, Plesk and similar panels let each site pick a PHP version. Export the per-site assignment so you can see which customers or departments still sit on old branches. The Hosting control panels security guide covers panel-side controls.
- Container images and registries. Scan every image in every registry for PHP packages and base image age, including tags that are not currently running. An SBOM per image makes this a query. See the SBOM operations guide.
- Source repositories. The
require.phpconstraint and anyconfig.platform.phpvalue incomposer.jsonshow which branch each application targets. Composer's documentation notes that the platform setting fakes the PHP version Composer sees, so a stale value can hide a mismatch with production; it recommends runningcheck-platform-reqsduring deployment. - External scanning. Internet-facing hosts that disclose a version (for example in an
X-Powered-Byheader) are what attackers see first; Cyfirma, as reported by Security Affairs, described PHP2Shell operators keeping hosts that still advertised older PHP. Use your attack surface tooling to find forgotten microsites and campaign domains, then turn off version disclosure withexpose_php = Offonce inventoried. See the Attack Surface Management Guide. - Vendor products and appliances. Commercial web applications, NAS devices and appliances often embed PHP. Ask each supplier which branch they ship and how they patch it, and record their answer in the asset register.
- Developer and Windows stacks. Local stacks such as XAMPP and PHP on IIS appear on servers that were "temporary". CVE-2024-4577 showed how exposed Windows PHP-CGI can be.
For each runtime, capture: host or image, owner, PHP branch, full package version and source (upstream, distribution, panel vendor, container base), SAPI, internet exposure, supplier end of support date, and the plan (upgrade, backport, extend, isolate, retire). That record is what turns a scan result into a programme. The CIS Control 2 Inventory and Control of Software Assets Guide covers the wider software inventory.
Upgrade path: from discovery to a supported branch
- Prioritise. Internet-facing first, then hosts holding valuable secrets, then by how far out of support the branch is. Anything on 8.1 or older that faces the internet is urgent; PHP 8.2 hosts need a date before 31 December 2026.
- Pick the target branch. Prefer 8.4 or 8.5 for new work. Check that the framework, CMS, plugins and extensions you use support it. Where code is on 7.x, plan a stepwise path, because each php.net migration guide covers one branch to the next.
- Scan the code statically. PHPCompatibility, a ruleset for PHP_CodeSniffer, checks code for cross-version compatibility against a target set with
testVersion. Run it in CI so new code cannot reintroduce removed features. - Fix deprecations on the current branch first. Turn on deprecation logging in a test environment and fix what it reports before you switch versions; deprecated features are the ones removed in the next branch.
- Update dependencies. Raise the
require.phpconstraint, update Composer packages, and remove or correct any staleconfig.platformvalue so the lock file matches the new runtime. - Test in a staging copy. Run automated tests and a smoke test of key journeys (login, checkout, uploads, scheduled jobs). Compare PHP error logs before and after.
- Roll out in rings. One low-risk site or host, then a small production group, then the rest. On control panels, switch per-site PHP versions in batches.
- Keep rollback safe. Roll back to the previous supported branch or a patched backport, never to an unpatched build. Keep the old version installed but unassigned for a fixed period, then remove it.
- Remove the old runtime. Uninstall unused PHP versions and retire old container tags, so nothing can drift back. A version left installed is a version someone will select.
The Patch Management Guide covers change windows and ring design across the wider estate.
Where identity fits
Old PHP applications tend to carry old credential habits: database passwords and API keys in plaintext config files readable by the worker, one shared database account across sites, and hosting panel tokens in deployment scripts. An upgrade is the cheapest moment to fix them, because the configuration is being touched and tested anyway. Move secrets out of web roots into a secrets manager or environment injection, give each site its own database account and worker user, and rotate any credential on a host that ran an exploitable branch while internet-facing. See the Secrets Management Guide.
Detection and measurement
- Log and alert on: new hosts or images appearing with an unsupported PHP branch; per-site PHP version changes on panels (especially downgrades); version disclosure headers on external scans; PHP error log volume and deprecation warnings after an upgrade.
- Track supplier dates: keep PHP branch, OS release and Application Stream end dates in the register, and alert 180 and 90 days before each.
Metrics:
- Percentage of PHP runtimes on a branch with at least 12 months of supplier security support left.
- Number of internet-facing runtimes on an unsupported, unpatched branch (target zero).
- Percentage of runtimes with a named owner and plan in the register.
- Median days from a branch reaching end of life to its last runtime being removed.
- Number of PHP 8.2 runtimes remaining, tracked weekly to 31 December 2026.
- Percentage of repositories with PHPCompatibility or an equivalent check in CI.
Common failure patterns
- Trusting
php -v. The CLI may differ from the web SAPI, and backported packages keep old version numbers. Teams either panic about patched hosts or ignore unpatched ones. - Buying extended support with no exit date. The bridge becomes the road, and the application never moves.
- Leaving old versions installed on panel servers. A customer or developer selects them again, and they never get the vendor rebuilds.
- Forgetting registries. The running fleet is clean but an autoscaler or rollback pulls an old image tag.
- Upgrading without a compatibility scan. A failed upgrade gets rolled back to an unpatched build, and the next attempt is months away.
- Treating hosting as someone else's problem. Agency and departmental sites on third-party hosting sit on old branches because no contract says who upgrades. The GoDaddy Managed WordPress Breach 2021 shows how much customer credential material a hosting platform can hold when its own systems are compromised.
Framework mapping
| Framework | Reference | Where it applies |
|---|---|---|
| NIST SP 800-53 Rev. 5 | SA-22 Unsupported System Components | Replace unsupported PHP or document alternative sources of support |
| NIST SP 800-53 Rev. 5 | CM-8 System Component Inventory; RA-5 Vulnerability Monitoring and Scanning; SI-2 Flaw Remediation; CM-7 Least Functionality | Runtime inventory, scanning, patching and removing unused versions |
| NIST CSF 2.0 | ID.AM-02; ID.RA-01; PR.PS-02 | Software inventory, identifying vulnerable runtimes, maintaining and replacing software commensurate with risk |
| CIS Controls v8.1 | Control 2, Safeguard 2.2 (authorised software is currently supported); Control 7 Continuous Vulnerability Management | Unsupported software flagged and handled as an exception; patching cadence. See the CIS Control 7 Continuous Vulnerability Management Guide. |
| ISO/IEC 27001:2022 Annex A | A.8.8 Management of technical vulnerabilities | Runtime vulnerability handling and end of life planning |
| CISA KEV | CVE-2026-109618; CVE-2026-109619; CVE-2019-11043; CVE-2024-4577; CVE-2012-1823 | Evidence that PHP runtime flaws are exploited |
Practitioner checklist
- Build a PHP runtime register covering servers, panels, containers, appliances and managed hosting, with branch, package version, source, SAPI and owner.
- Check patch state against each supplier's security tracker, not the upstream version string.
- Remove internet exposure or patch every runtime on 8.1 or older now.
- Schedule every PHP 8.2 runtime for upgrade before 31 December 2026.
- Deploy new work on PHP 8.4 or 8.5.
- Add PHPCompatibility or an equivalent to CI and fix deprecations before switching branches.
- Give every extended support contract a written retirement date and CVE commitment.
- Uninstall unused PHP versions on servers and panels and retire old image tags.
- Rotate credentials on hosts that ran exploitable branches while exposed.
- Alert 180 and 90 days before each branch, OS and stream end date.
Standards and references
- PHP: Supported Versions
- PHP: Unsupported Branches
- Red Hat: RHEL Application Streams Life Cycle
- Ubuntu: CVE-2026-109618 security notice
- Debian: Security Tracker CVE-2026-109618
- CISA: Known Exploited Vulnerabilities Catalog
- Composer: Config (platform and platform-check)
- PHPCompatibility: PHP Compatibility Coding Standard for PHP_CodeSniffer
Related NHI Mgmt Group resources: PHP and WordPress Security Guide · Operating System End of Life and Extended Support Guide · PHP2Shell · PHP2Shell campaign tracker · Patch Management Guide