How to check the PHP version on a VPS, update it on Ubuntu and Debian, and confirm the CVE-2026-109618 fix is actually running.

In October 2026 the PHP project fixed two critical vulnerabilities, one of them CVE-2026-109618. If a PHP site runs on your server, three questions matter: which PHP version is installed, whether it contains the fix, and whether the fixed code is the code actually running. This guide shows how to update PHP on Ubuntu and Debian, and how to avoid a trap: on Ubuntu, php -v can keep printing the old number even after the fix is in.

TL;DR. On Ubuntu, check the package version with dpkg rather than trusting php -v: Ubuntu backports the fix into the old version, so php -v on 24.04 still says 8.3.6. On Debian 12 and 13 the fixed package reports a new number itself (8.2.35, 8.4.27), but comparing the package version is reliable on every system. Upgrade with apt, then restart PHP-FPM or Apache, because a running process does not pick up new code on its own. If you cannot update yet, there are partial mitigations, and none of them makes the setup safe. Information as of 27 October 2026.

What happened: the PHP vulnerability CVE-2026-109618 and its sibling

On 21 October 2026 php.net announced PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. (The changelog dates 8.5.12 and 8.4.27 as 22 October, so "21-22 October" is the accurate range.) The releases close two critical flaws: CVE-2026-109618 ("RCE via OOM corruption") and CVE-2026-109619 ("RCE via stale global state"). Both score 9.2 on CVSS v4.0 and both are rated Critical.

RCE means remote code execution: someone else's code runs on your server. "Without authentication" means an attacker needs no account on your site or your server to start. That describes what the bug allows. This article does not claim that anyone has been attacked, and you should not infer it from a CVE number alone.

The affected ranges are everything below the fixed release in each branch: 8.2 before 8.2.35, 8.3 before 8.3.36, 8.4 before 8.4.27, 8.5 before 8.5.12. Every way of serving PHP to the web is in scope (these are called SAPIs): PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, LiteSpeed. The risk is highest with mod_php, where PHP is built into Apache. What the advisories say in detail:

  • CVE-2026-109618 is confirmed on mod_php; by code analysis FPM is also susceptible, but no full exploit has been shown for it;
  • for CVE-2026-109619 the session lifecycle path was verified on both mod_php and FPM.

Only an update fully fixes the problem. The rest of this guide covers how to apply it and how to confirm it worked.

Which PHP version is on the server, and how does it run

First, two facts: what is installed, and which mechanism answers your site's requests. You need the second one to restart the right service later. Connect over SSH and run the commands in the card below. We captured them on a test server running Ubuntu 24.04.5.

  • php -v prints the version of the command-line PHP (note the cli tag). It is not always the one serving your site.
  • dpkg -l lists installed packages, grep keeps the PHP lines, awk prints only the name and version.

How to read the list. A php8.3-fpm package (your number may differ) means PHP runs as its own FPM service and the web server hands requests to it. A package with mod-php in its name means PHP is embedded in Apache. Both can be present; then update and restart both. The examples below use php8.3-fpm, so substitute the name from your own list.

Why php -v on Ubuntu 24.04 still says 8.3.6 when the fix is installed

Ubuntu does not jump to a new PHP version inside a release. It takes the fix from the new upstream version and applies it to the version you already have (a backport), keeping the base version number. So on a fixed Ubuntu 24.04, php -v still prints "PHP 8.3.6", not 8.3.36: on our test server the package contains the fix and php -v reports 8.3.6. On Ubuntu 22.04 the fixed package prints the full package version, "PHP 8.1.2-1ubuntu2.28". Debian behaves differently: it ships the upstream point release, so the fixed package itself prints "PHP 8.2.35" (Debian 12) or "PHP 8.4.27" (Debian 13). Those values come from a check in clean images of these systems. The same signal reads differently on different systems, so the dependable test is to compare the package version against the table below.

System

Package

Fixed version

What php -v prints

Source

Ubuntu 24.04 (noble)

php8.3

8.3.6-0ubuntu0.24.04.13

PHP 8.3.6

USN-8948-1, 21 October 2026

Ubuntu 22.04 (jammy)

php8.1

8.1.2-1ubuntu2.28

PHP 8.1.2-1ubuntu2.28

USN-8948-1

Debian 12 (bookworm)

php8.2

8.2.35-1~deb12u1

PHP 8.2.35

DLA-4848-1

Debian 13 (trixie)

php8.4

8.4.27-1~deb13u1

PHP 8.4.27

DSA-6574-1

ondrej/php PPA for Ubuntu 24.04 and 22.04

php8.3, php8.4

8.3.36, 8.4.27

not checked

Launchpad, 21 October 2026

We matched these versions against the install candidates in clean Ubuntu 24.04, Ubuntu 22.04, Debian 12 and Debian 13 images on 27 October 2026, and each candidate equals the table value. For the PPA we did not check the 8.2 and 8.5 branches. Ubuntu 26.04 was not part of the check: if you run it, compare against Ubuntu's own security notice.

Method one: look for the CVE number in the installed package's changelog. If the entry is there, the fix is in the package. The changelog lives at /usr/share/doc/php8.X-common/changelog.Debian.gz (put your own digit in place of X); it exists on all four systems, and on Debian the lines with the CVE read slightly differently from our example. -m2 stops after two matches. Then apt-cache policy shows Installed (what you have) and Candidate (what apt is ready to install).

We also tried apt-get changelog, but on our test server it returned a 404: for this package the changelog is not available on Ubuntu's servers. The file under /usr/share/doc is more dependable, since it sits on your own machine.

Method two is stricter: compare the installed package version with the fixed one from the table. Debian-style versions contain tildes and suffixes, so a plain string comparison gives wrong answers. dpkg --compare-versions A ge B answers "is A at least B". The first command below uses the real package on our server. The second substitutes a build ending in .12: it is an example of how the command reports an older package, and no such package was installed on our server.

  • FIXED is the fixed version from the table; replace it and the package name (php8.3-fpm) with your own.
  • dpkg-query -W -f="\${Version}" prints the installed package version.
  • OK means you have the fixed version or newer. UPDATE NEEDED means update.

How to update PHP on Ubuntu and Debian

Take a copy of the site and its database first. Rolling back a package upgrade is harder than making a copy now. The WeaselCloud panel has no snapshots or backups, so the copy is yours to make; the guide on backing up a VPS yourself covers it.

The commands are the same on Ubuntu and Debian. The first refreshes the list of available package versions, the second installs updates, security patches included. The same pair appears in the guide to securing a fresh VPS. If you are logged in as root or sudo is not installed, run the commands without sudo:

sudo apt update && sudo apt upgrade

apt prints the list of packages it will upgrade and asks for confirmation. Your PHP packages (php…) will be among them. We do not print that output here, because it depends on your server. If you installed PHP from the ondrej/php repository, the packages update from there. On Debian 12 and 13 it is the same flow, with packages named php8.2… and php8.4…; on Ubuntu 22.04 they are php8.1….

To confirm nothing is left to upgrade, run apt-get update and count PHP packages in the upgradable list. Zero means no newer PHP packages are waiting. On our test server the package was already fixed.

Now the step people skip. The files on disk are new, but the running PHP-FPM process keeps the old code in memory until you restart it. For FPM (use your own version number):

sudo systemctl restart php8.3-fpm

The service name depends on the system: php8.1-fpm (Ubuntu 22.04), php8.2-fpm (Debian 12), php8.3-fpm (Ubuntu 24.04), php8.4-fpm (Debian 13). If PHP is embedded in Apache, restart Apache instead: sudo systemctl restart apache2; its packages are named libapache2-mod-php8.X. A restart can briefly interrupt request handling, so pick a quiet moment, but do not put it off.

To confirm the process is new, check the service state, the process start time, and which file the running process points to (replace the PID in the ls command with the master process number from the PID column).

  • active means the service is running. The STARTED column shows when the processes began; it should be later than the package upgrade.
  • /proc/PID/exe is a link to the program the process was started from. If the file was replaced while the process kept running, the path gets a (deleted) suffix: the process is still the old one and needs a restart. There is no such suffix in our output.
  • The modification time of /usr/sbin/php-fpm8.3 matches the build date shown by php -v (19 October). That is the package build date, not the moment you installed it. So "the process is newer than the file" is a weak signal on its own. The (deleted) marker is more reliable, as is the habit of restarting the service after every PHP update.

What to do if you cannot update right now

Sometimes a site depends on a specific PHP version and needs testing time. There are partial mitigations. To be clear up front: they do not make the setup safe and do not replace the update. They narrow the exposure while you prepare the move.

Mitigation

How

What to know

Turn off session.upload_progress.enabled

Set it to 0 in php.ini, the FPM pool or the server config; then restart all workers

Do not set it with ini_set() or .user.ini: they are not suitable for this. It closes the confirmed session paths; other variants remain

memory_limit=-1 via php_admin_value

In the FPM pool or Apache configuration, so applications cannot override it; then restart the workers

Make sure no pool, directory or application sets a finite limit. This is the main configuration measure for CVE-2026-109618, but not full protection. Do not lower the memory limit

Limit request size

At the web server or proxy; post_max_size 8M (32M if the site needs file uploads), upload_max_filesize below it

Shrinks the attack surface, does not close the hole

Memory limit on the container (cgroup)

If PHP runs in a container

An availability boundary only, not protection. Best combined with a policy that kills only the affected worker; no guarantee

For CVE-2026-109619: pm.max_requests=1

In the FPM pool settings, if performance allows

Each worker serves one request and is replaced, so server load goes up

On PHP 8.5: fatal_error_backtraces=0

A setting in the PHP configuration

8.5 only

Do not use RLIMIT_AS or RLIMIT_DATA.

One more note on session.upload_progress.enabled. On 23 October 2026 php.net published an informational advisory (CVE-2026-115560; the full advisory is promised with the next regular release). It suggests setting session.upload_progress.enabled=0 until the next regular bugfix release, to fully protect against an unlikely RCE vector. That recommendation holds even for servers that are already patched. The scenario applies to applications that switch session.serialize_handler to php through ini_set() before session_start() while upload progress is on. The authors of GHSA-6wmf-4rv5-p3rp likewise advise keeping it off after patching if you do not use the feature. Source: https://www.php.net/archive/2026.php.

Here is the first one on the test server. session.upload_progress.enabled controls tracking of upload progress in the session. We read the value in FPM, create a config file with one line (its content is in the card), restart the service, and read the value again. php-fpm8.3 -t validates the configuration so a typo does not take the site down. Note that php-fpm8.3 -i reports FPM's own settings, not the command line's.

On, then Off. If any of your sites relies on upload progress tracking through sessions, it will stop working: that is the price of this measure. The file path above is for FPM; Apache keeps its configuration in a different directory, which you can find in the output of php -i.

PHP 8.1 and older, and self-built PHP

Each PHP branch has a date until which the project ships security fixes. After that the branch is end-of-life (EOL): new vulnerabilities are not fixed in it.

Branch

Fixed in

Security support from the PHP project

7.4

no release; source-build branch exists

ended 28 November 2022

8.0

no release; source-build branch exists

ended 26 November 2023

8.1

no release; source-build branch exists

ended 31 December 2025

8.2

8.2.35

until 31 December 2026

8.3

8.3.36

until 31 December 2027

8.4

8.4.27

until 31 December 2028

8.5

8.5.12

until 31 December 2029

If you run PHP 8.1 or older, there are no releases with the fix for your branch. The PHP security team did publish minimal source backports for 7.4, 8.0 and 8.1 in the git branches PHP-7.4-CVE-2026-109618-109619, PHP-8.0-CVE-2026-109618-109619 and PHP-8.1-CVE-2026-109618-109619 of the php/php-src repository, meant for people who build from source. On Ubuntu 22.04 the php8.1 package at 8.1.2-1ubuntu2.28 contains a fix released by the distribution itself (see the table above), so install that update through apt. Still, do not plan around a branch the project has dropped: schedule a move to 8.3 or newer and test your plugins and code on a copy first. We did not check the support dates of the distributions themselves.

If PHP was built from source, apt knows nothing about it and will not update it. You have three options: rebuild from a fixed release (8.2.35, 8.3.36, 8.4.27, 8.5.12 or newer), rebuild from one of the backport branches, or move to the distribution's packages, which is usually easier to maintain. Note the difference: a build from a release reports the fixed version in php -v, while a build from a backport branch keeps the same number, so the number cannot prove the fix.

How to check whether anything on the server changed

These checks do not prove the server is clean and guarantee nothing: finding no suspicious files does not mean there were none. Their purpose is modest: to spot obvious oddities quickly. For a PHP site, start with recently modified files.

The first command lists PHP files under /var/www changed in the last seven days; the second lists files newer than the PHP-FPM binary. The output below comes from our test server, where the only file found is our own test index.php, created by us for this check.

On a working site the lists will be longer: CMS updates, uploaded themes and your own edits all change files. The goal is not an empty list but recognising every file in it. A file you did not create or upload, especially in an uploads directory or with an odd name, deserves a closer look.

The second place for a quick glance is scheduled jobs. This is /etc/cron.d and the user crontab directory on our test server. The names are familiar (certbot, php, sysstat), and there are no user crontabs.

For a broader picture you can look at the processes using the most CPU (ps -eo user,pid,etime,cmd --sort=-pcpu | head -5) and the number of established connections (ss -tnp state established | wc -l). We do not show our output here: it depends on your server, and you can only read it if you know what normally runs there.

If you find a file or job you did not create, do not delete it right away. Keep a copy and the command output, then open a support ticket. For lasting protection, go through the first-10-minutes checklist: SSH keys, firewall, updates.

FAQ

How can I tell whether PHP is fixed if php -v shows 8.3.6?

Look at the package version, not just the output of php -v. On Ubuntu 24.04 the fixed package is 8.3.6-0ubuntu0.24.04.13, and php -v still prints 8.3.6. On Debian 12 and 13 the fixed package reports the new number itself (8.2.35 and 8.4.27), but comparing the package version with dpkg --compare-versions is reliable on every system. You can also look for the lines with CVE-2026-109618 in the package changelog file.

Do I need to restart PHP after updating?

Yes. The files on disk are replaced, but running processes keep the old code until they restart. For PHP-FPM that is sudo systemctl restart php8.3-fpm (use your own version number); for PHP inside Apache, restart Apache. You do not need to reboot the whole server for PHP.

What if I cannot update PHP right now?

Set memory_limit=-1 through php_admin_value in the FPM pool or Apache configuration, turn off session.upload_progress.enabled, limit request size at the web server, and if PHP runs in a container, add a container memory limit as an availability boundary, not as protection. Do not lower PHP's memory limit. These are partial measures and do not make the setup safe, so set yourself a date for the update. Do not use RLIMIT_AS or RLIMIT_DATA.

My server runs PHP 8.1. Is it affected?

There are no PHP 8.1 releases with the fix: the branch reached end of life on 31 December 2025, though a backport branch, PHP-8.1-CVE-2026-109618-109619, exists for source builds. On Ubuntu 22.04 the fix is in the php8.1 package at 8.1.2-1ubuntu2.28, and you should install it. Plan a move to a supported branch.

Does this mean my server has already been compromised?

No. A vulnerability is a possibility, not a fact, and a CVE number alone says nothing about whether it was used against your server. Update PHP, restart the service, and spot-check files and scheduled jobs as described above.

Takeaways

  • CVE-2026-109618 and CVE-2026-109619 are fixed in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35; earlier versions of those branches are affected.
  • Compare the package version with dpkg: on Ubuntu 24.04 php -v shows 8.3.6 even after the fix, on Ubuntu 22.04 it prints the full package version, and on Debian 12 and 13 the fixed package itself reports 8.2.35 and 8.4.27.
  • Upgrade through apt and restart PHP-FPM or Apache; without a restart the process stays old.
  • If you cannot update, apply the partial mitigations, remembering that they do not make the setup safe.
  • For PHP 8.1 and older there are no releases with the fix (backport branches exist for source builds): plan a move to 8.3 or newer.
  • php.net advises keeping session.upload_progress.enabled=0 even on updated servers until the next regular release (the 23 October 2026 advisory on CVE-2026-115560), if you do not need the feature.
  • Checking files and scheduled jobs can reveal obvious oddities, but it does not guarantee a clean server.

🎁 40% off the first month of a new VPS. Promo code GUIDE40
Need a server for your tasks? The first month at a discount.
Enter GUIDE40 at checkout. One use per customer.
Pick a VPS and claim the discount →