Awareness

How to Check If Your PHP Version Is Vulnerable

Eng. Donya Bino Published  ·  9 min read

Most site owners think they know their PHP version, because they ran php -v once, saw a number, and assumed that was the answer.

It usually is not the answer, and that gap is where real incidents happen, because the PHP in your terminal is often not the PHP that serves your traffic, and the version number on a Linux distribution frequently does not reflect whether a security patch has actually been applied.

Here is how to check properly, in the order that actually works.

Important Disclaimer

This article is intended for educational and defensive purposes only, and the techniques described here are shared to help site owners and administrators assess systems they own or are authorized to administer.

Do not use these techniques against systems you do not own or do not have explicit written permission to test, because unauthorized access and investigation is illegal in most jurisdictions.

The author assumes no liability for any damages, legal consequences, or other outcomes resulting from the use or misuse of this information, so always work within your authorization, and stay legal, stay ethical, stay responsible.

Step One: Find the PHP That Actually Serves Traffic

Quick Security Checklist

  • Scan your system or website
  • Update all dependencies
  • Change passwords
  • Enable 2FA

The first mistake is checking the command line binary and calling it done.

A server can have several PHP installations, one for the CLI, one for Apache, and several for different PHP-FPM pools, and they can all be different versions. The one that matters is the one processing web requests, because that is the one an attacker can reach.

Check What You Have

php -v

This tells you the CLI version, which is a starting point rather than an answer.

Find Every PHP Binary on the System

for p in /usr/bin/php[0-9]* /usr/sbin/php-fpm* 
/usr/local/bin/php /opt/*/bin/php; do
  [ -x "$p" ] && printf '%-45s %s\n' "$p" 
"$($p -v 2>/dev/null | head -1)"
done

If this returns more than one version, you need to establish which one your site uses.

Check the Running Service

systemctl list-units --type=service --state=running | 
grep -Ei 'php|fpm'

On Apache with mod_php, the module list tells you what is loaded:

apachectl -M 2>/dev/null | grep -i php

If you run a control panel, the panel usually shows the active PHP version per site, and it is often the fastest way to see the truth.

Confirm With a Live Request

The most reliable check is to look at what your site actually reports, so create a temporary file that outputs the version and delete it immediately after.

Do not leave this file in place, because it exposes information to anyone who finds it.

Step Two: Compare Against Supported Versions

Once you know the real version, compare it against the support timeline, because an unsupported branch receives no fixes regardless of how many vulnerabilities are discovered.

PHP branches receive active support for two years and security-only support for two more, and after that they are end of life.

Branch

Support Status

8.5

Fully supported

8.4

Fully supported

8.3

Security support only

8.2

Security support, nearing end

8.1 and older

End of life, no fixes

If you are on 8.1 or older, you are running software that will never be patched again, and the answer to the question is yes, you are vulnerable, regardless of which specific bugs exist today.

Step Three: Check for Known Critical Issues

An up-to-date branch can still have an unpatched issue if you have not applied the latest release, so check the fixed version for your branch.

Recent critical PHP vulnerabilities have involved memory-safety bugs that allow unauthenticated remote code execution, and the fix exists as a specific release per branch. The practical approach is to check whether your installed version matches or exceeds the fixed version for your branch.

If you are below the fixed version for your branch, you are exposed to that specific issue even though your branch is technically supported.

Step Four: Verify the Patch Is Actually Applied

This is the step that separates a real audit from a superficial one.

On Debian and Ubuntu, security fixes are frequently backported without changing the upstream version number, which means a box showing the same version string as another box may be patched or unpatched depending on when the package was built.

Check the Package Version

dpkg-query -W -f='${Package} ${Version}\n' php8.3-common

Check the Changelog for the CVE

zcat /usr/share/doc/php8.3-common/changelog.Debian.gz | 
grep -c 'CVE-2026-109618'

A count above zero means the fix is present in the package, even if the version string looks unchanged.

On Red Hat Based Systems

rpm -q --changelog php-common | grep -m2 -E 
'CVE-2026-10961[89]'

If the changelog does not mention the fix, the package is not patched, and the version number is not evidence of anything.

Step Five: Restart the Service

Installing an update does not change the code that is already loaded in memory.

If you update the package and do not restart PHP-FPM or Apache, the old code keeps serving requests, and the vulnerability remains exploitable even though the files on disk are patched.

sudo systemctl restart 'php*-fpm.service'
sudo systemctl restart apache2


Confirm the restart succeeded before you conclude anything.

Step Six: Apply Interim Mitigations If You Cannot Patch Yet

Sometimes patching requires a maintenance window, and in that gap you need something that reduces exposure.

Two settings help in the interim, and they are worth applying immediately.

  • Disable upload progress. This feature has been implicated in several PHP attack chains, and most sites do not need it. Turn it off in the pool configuration or in php.ini, and remember that ini_set() and .user.ini are not sufficient for this setting.
  • Tighten post_max_size. Set it to the smallest value your site can tolerate, such as 8M if you do not accept file uploads, or 32M if you do. A smaller limit reduces the size of the payload an attacker can send.

These are stopgaps, and they reduce risk rather than removing it.

Step Seven: Check Whether You Have Already Been Hit

If your PHP version was vulnerable and the server was reachable from the internet, the last step is to look for evidence that the issue was exploited before you patched it.

The clearest signal is process lineage, because a PHP worker that has spawned a shell or a downloader is almost always compromised.

pstree -ap | grep -A3 -E 'php-fpm|apache2|httpd'

An unexpected sh, bash, curl, or wget child process under a web worker is a strong indicator.

The second signal is file creation, because attackers write their tools to disk. Look for new executable files in upload directories and temporary directories that do not match any deployment.

The third signal is outbound connections, because a compromised worker usually calls home. Review outbound traffic from the web server for unfamiliar destinations, especially on uncommon ports.

If any of these signals are present, the question is no longer whether you are vulnerable, it is whether you are already compromised, and the response changes from patching to incident response.

Two Real Scenarios

Scenario 1: The Forgotten FPM Pool

The Setup

A server was upgraded from PHP 8.1 to PHP 8.3, and the upgrade covered the CLI and the default pool, and everyone assumed the job was complete.

The Problem

A second FPM pool serving an older site was still configured to use the 8.1 binary, and that site remained end of life and unpatched.

The Check That Finds It

The binary search returns two FPM binaries, and the service list shows two pools running, and the older one is still bound to a public virtual host.

The Lesson

One server can run several PHP versions at once, and the one you forgot is the one that gets exploited.

Scenario 2: The Patched Package, The Unpatched Process

The Setup

An administrator applies the security update correctly, confirms the package version, and moves on.

The Problem

The PHP-FPM service is not restarted, so the old code stays in memory and the vulnerability remains live.

The Check That Finds It

The process start time is earlier than the package install time, which means the running process predates the patch.

The Lesson

Patching is a two-part action, and the second part is the restart.

Quick Reference: PHP Vulnerability Check

Step

Action

1

Find every PHP binary and the active FPM pools

2

Confirm the version serving live traffic

3

Compare against the supported branch list

4

Check the installed version against the fixed release for that branch

5

Verify the package changelog for the CVE on Linux

6

Restart PHP-FPM or Apache after patching

7

Apply interim mitigations if you cannot patch

8

Check process lineage, file creation, and outbound traffic

The Bottom Line

Checking whether your PHP version is vulnerable is not one command, it is a sequence, and the sequence matters because each step catches a different mistake.

Find the PHP that actually serves traffic, because the CLI is not the answer. Compare against the supported branches, because an end of life branch is vulnerable by definition. Verify the patch in the package changelog, because on Linux distributions the version string can be misleading. Restart the service, because installed code is not running code. Apply interim mitigations if you cannot patch today, and check for compromise if you were exposed.

The version number is a starting point, and the audit is what tells you whether you are actually safe.

FAQ

Is running php -v enough to check if I am vulnerable?

No, because it reports the CLI version, which may differ from the version serving web traffic, and because distribution patches often do not change the version string.

What PHP versions are end of life?

8.1 and older are end of life and receive no security fixes, while 8.2 is in security-only support and nearing its end.

Why does my patched server still show an old version number?

Because Debian and Ubuntu backport security fixes without changing the upstream version, which is why the package changelog is the reliable check.

Do I need to restart after patching PHP?

Yes, because the running process keeps the old code in memory, and without a restart the vulnerability remains exploitable.

How do I know that my server had been previously compromised?

Check for shell/downloader child of the web workers process, new executables in upload directories, and unusual outbound connections initiated by the web server.

What should I do if I am not able to patch this immediately?

Disabling upload progress and reducing post_max_size can be used as a temporary solution, and treat them as stopgaps rather than fixes.

Professional Services

Explore Our Cybersecurity Services

Our insights are backed by hands-on service delivery. If your business needs professional cybersecurity support, our UK-based specialists are ready to help.

© 2016 – 2026 Red Secure Tech Ltd. Registered in England and Wales — Company No: 15581067