SSD Nodes Learn Hosting plans →
How to do am Matt ConnorBy Matt Connor

Apply PHP Security Update for Ubuntu, Confam Am

php -v no fit tell you if PHP2Shell patch don land. See how to check the Ubuntu package version, restart php-fpm and Apache, and sort Docker and cPanel.

How to apply PHP security update for Ubuntu, quick answer

To apply PHP security update for Ubuntu, run sudo apt update and sudo apt upgrade. After that, restart the PHP service wey dey serve your site. Then check the package version against the Ubuntu security notice. No use php -v as proof. Na the package revision go tell you whether your server don patch.

We go use PHP2Shell as the example. PHP2Shell na two critical bugs, CVE-2026-109618 and CVE-2026-109619, wey PHP fix on 21 October 2026. The steps no tie to this one bug. Next time PHP get security notice, you fit follow the same road.

Wetin happen with PHP2Shell

On 21 October 2026, the PHP project release 8.5.12, 8.4.27, 8.3.36 and 8.2.35. php.net talk say these releases fix two critical bugs wey fit allow unauthenticated remote code execution. Remote code execution (RCE) mean say person wey never login fit make your server run code wey dem choose. The two GitHub advisories give both bugs CVSS v4 score of 9.2, wey be Critical.

  • CVE-2026-109618, "RCE via OOM corruption". OOM mean out of memory. If PHP run out of memory at the wrong moment, some request data fit dey half ready. The cleanup step fit then treat that bad data as if e correct.
  • CVE-2026-109619, "RCE via stale global state". Some state wey belong to one request fit still dey after im memory don free. The next request wey the same worker handle fit use that old state before normal setup reset am.

php.net talk say every PHP install wey dey serve web requests dey at risk. That one include PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. Dem talk say mod_php get the highest risk, because dem don show exploit where one request fit start the attack before any application code run. So WordPress or Laravel no fit block am. The bug dey inside PHP itself, under your app.

For PHP 8.1 and older, the PHP project no release any fix. php.net talk say make you ask your distribution or LTS vendor, or move to supported version. The PHP security team put small source backports for 7.4, 8.0 and 8.1 as git branches for php-src, but those ones no be package wey apt fit install. Also note: the 8.2.35 announcement talk say PHP 8.2 go reach end of life on 31 December 2026.

Why php -v no fit tell you if PHP don patch

Ubuntu no dey jump to new upstream PHP version inside LTS release. Ubuntu take the fix, put am inside the PHP version wey e first ship, then give the package new revision number. Na why USN-8948-1 and USN-8948-2, wey Ubuntu publish on 21 October 2026, list these fixed builds:

  • Ubuntu 26.10: php8.5 8.5.9-0ubuntu2.1
  • Ubuntu 26.04 LTS: php8.5 8.5.4-0ubuntu1.5
  • Ubuntu 24.04 LTS: php8.3 8.3.6-0ubuntu0.24.04.13
  • Ubuntu 22.04 LTS: php8.1 8.1.2-1ubuntu2.28
  • Ubuntu 20.04 LTS: php7.4 7.4.3-4ubuntu2.29+esm5, only through Ubuntu Pro

Look the 24.04 line well. Upstream fix na 8.3.36, but the Ubuntu fixed build still start with 8.3.6. php -v dey print only the upstream part. So 24.04 server wey don patch and the one wey never patch go both show 8.3.6. Na the part after the dash, 0ubuntu0.24.04.13, wey change. That part na wetin you go check.

22.04 dey different. The PHP project no fix 8.1 at all, but Ubuntu 22.04 still get fixed php8.1 from the security pocket, free. For 20.04, the fix come only through Ubuntu Pro. USN-8948-2 also list 18.04 under Ubuntu Pro, and 16.04 and 14.04 under the Legacy Support add-on. If you never set am up, read how Ubuntu Pro work on one server before you decide.

Both Ubuntu CVE pages, for CVE-2026-109618 and CVE-2026-109619, mark the priority as Critical and show the same fixed versions.

Step 1: Find the PHP branch and the FPM unit for your server

No write php8.3 from memory. Ubuntu 24.04 carry php8.3, and 26.04 carry php8.5. Ask the machine:

php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . PHP_EOL;'
systemctl list-units --type=service --all 'php*'

The first command go print the branch, like 8.3 or 8.5. The second one go show the FPM unit, like php8.3-fpm.service. If the php command no dey, na because php-cli no install. Use the unit name from systemctl to know the branch.

If no FPM unit show, your site fit dey run through Apache mod_php. Check am:

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

If you see php_module, Apache dey load PHP inside imself. Keep that one for mind, because e get im own restart step below.

Save the branch inside variable so the next commands go fit your server:

PHPV=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
echo "$PHPV"

Step 2: Check the package version against the security notice

Every PHP package for one branch come from the same source, so php8.3-common, php8.3-fpm, php8.3-cli and libapache2-mod-php8.3 carry the same version. Print the installed version:

dpkg-query -W -f='${binary:Package} ${Version}\n' "php${PHPV}-common"

On 24.04 e go print something like php8.3-common 8.3.6-0ubuntu0.24.04.13. Now compare am with the fixed version from the notice. dpkg --compare-versions sabi how Debian version strings dey sort, so e no dey confuse 8.3.6 and 8.3.36 like normal text sort.

FIXED=8.3.6-0ubuntu0.24.04.13   # change am to the line for your release
HAVE=$(dpkg-query -W -f='${Version}' "php${PHPV}-common")
if dpkg --compare-versions "$HAVE" ge "$FIXED"; then
  echo "patched: $HAVE"
else
  echo "NOT patched: $HAVE"
fi

The man page talk say dpkg --compare-versions return exit status 0 when the condition true, and 1 when e no true. Use the word operators like ge. The old < and > forms don obsolete, and the man page warn say dem get confusing behaviour.

If the docs folder dey your server, you fit also search the package changelog for the CVE number. First check whether the file dey at all, because some trimmed-down images no install docs:

ls -l /usr/share/doc/php${PHPV}-common/
zgrep -c CVE-2026-109618 /usr/share/doc/php${PHPV}-common/changelog.Debian.gz

If zgrep print a number wey pass 0, the changelog mention the fix. If the file no dey, no worry. The version check above na the one wey count.

Did your PHP come from Ubuntu or from ppa:ondrej/php?

Plenty WordPress and Laravel servers no use Ubuntu PHP at all. Dem add ppa:ondrej/php so dem fit run newer PHP than wetin Ubuntu ship. Na Ondřej Surý dey maintain that PPA, no be Ubuntu security team. E get im own version numbers. Check where your build come from:

apt-cache policy php${PHPV}-common

The output show the installed version and the repository line wey e come from. If the line mention ppa.launchpadcontent.net/ondrej, your PHP come from the PPA. If e mention the -security pocket for your release, like noble-security, na Ubuntu build.

This one matter because the version from the Ubuntu notice no be the right test for PPA build. Make we say your PPA build na older 8.3.35 one. Run this:

dpkg --compare-versions 8.3.35-1+ubuntu24.04.1+deb.sury.org+1 ge 8.3.6-0ubuntu0.24.04.13 && echo "looks patched"

E go print looks patched, because 35 big pass 6. But 8.3.35 na the release before the fix. So if you dey use the PPA, compare against the PPA fixed build. On 21 October 2026 the PPA publish 8.3.36-1+ubuntu24.04.1+deb.sury.org+1 for 24.04 and 8.3.36-1+ubuntu22.04.1+deb.sury.org+1 for 22.04. For other branches, check the PPA page for the build wey carry the fixed upstream release.

One more thing about the PPA. Im Launchpad page talk say dem dey merge am into packages.sury.org/php. The page still say you fit use the PPA for 22.04 and 24.04, but for 26.04 the canonical source na packages.sury.org/php.

Step 3: Install the update

Before you upgrade, write down when PHP-FPM start last. You go need am to prove say restart happen:

FPM=$(systemctl list-units --type=service --plain --no-legend 'php*-fpm.service' | awk '{print $1}')
echo "$FPM"
systemctl show -p ActiveEnterTimestamp "$FPM"

Now update:

sudo apt update
sudo apt upgrade

USN-8948-1 talk say standard system update go make all the changes wey dey needed. When apt upgrade finish, run Step 2 again. The check go print patched. If apt stop with dependency error, fix that one first with how to fix broken packages with apt, because half-done upgrade fit leave old PHP for disk.

Step 4: Prove say the running PHP-FPM na the new one

apt change the file for disk. But process wey dey run before the upgrade still hold the old code inside memory. E go keep serving with the old code until you restart am. So package wey show patched no mean say your site don safe yet.

Check the FPM master process:

systemctl show -p ActiveEnterTimestamp "$FPM"
sudo readlink /proc/$(systemctl show -p MainPID --value "$FPM")/exe

Compare the timestamp with the one you write before the upgrade. If e still be the old time, PHP-FPM never restart. The readlink line confam am another way. When dpkg replace /usr/sbin/php-fpm8.3, the old file comot from disk, so a process wey still dey run am go show /usr/sbin/php-fpm8.3 (deleted).

Ubuntu Server docs talk say from 24.04, needrestart dey restart affected services by itself by default. But no just assume am. Your server fit get different setting, or you fit run the upgrade in a way wey skip am. If the timestamp old or you see (deleted), restart am yourself:

sudo systemctl restart "$FPM"
systemctl show -p ActiveEnterTimestamp "$FPM"
sudo readlink /proc/$(systemctl show -p MainPID --value "$FPM")/exe

Healthy result: the timestamp now be few seconds ago, and readlink print the binary path with no (deleted). You fit also ask needrestart to list any other thing wey still dey run old code, without restarting anything:

sudo needrestart -r l

Apache with mod_php: restart apache2 too

If you build your server with a LAMP stack on Ubuntu 24.04 and use libapache2-mod-php, PHP no be separate service. PHP dey load inside every Apache process as libphp8.x.so. Restart of php-fpm no touch am, because php-fpm no exist for that setup. And remember: php.net call mod_php the highest-risk setup for this bug.

After the upgrade, check whether any Apache process still hold the old library:

sudo grep -l 'libphp.*(deleted)' /proc/[0-9]*/maps 2>/dev/null

Each path wey this command print na process wey still dey run the old PHP. Restart Apache, then check again:

sudo systemctl restart apache2
sudo grep -l 'libphp.*(deleted)' /proc/[0-9]*/maps 2>/dev/null
ps -o pid,lstart,cmd -C apache2

The grep must print nothing this time. The ps start times must be after your upgrade.

PHP inside Docker: apt upgrade no reach am

If your app run inside container, the PHP wey dey serve am live inside the image. apt upgrade for the host no touch am at all. You must pull the image wey carry the fix and recreate the container. If Compose still new to you, start with Docker Compose basics on a VPS.

Check your exact tag on Docker Hub before you pull. No assume. As of 22 October 2026, Docker Hub show different digest for php:8.3-fpm and php:8.3.36-fpm, so docker pull go report different digest for each tag. But the image for each architecture, like amd64, na the same one under both tags, so the floating php:8.3-fpm tag dey carry 8.3.36. The 8.3 Alpine variants come rebuild one day later, on 22 October. The official image no get any fixed 8.1 tag: the newest 8.1 tags na 8.1.34 builds wey last update on 2 January 2026.

For Compose project wey use the official image straight:

docker compose pull
docker compose up -d
docker compose exec php php -v

Change php to the name of your service. The official images build PHP from upstream source, so here php -v dey useful: e must show 8.3.36, 8.4.27, 8.5.12 or 8.2.35. If you get your own Dockerfile wey start with FROM php:8.3-fpm, rebuild with fresh base image first:

docker compose build --pull
docker compose up -d

up -d go recreate any container wey im image change. Container wey still dey run from old image still get the bug, even after you pull.

cPanel and shared hosting: na your host hold the key

If your WordPress site dey on shared hosting or cPanel, you no get root access. The hosting company control the PHP build. None of the commands above go work for you.

So your only move na to ask. Open ticket and ask two things. One: which PHP build dey serve my site? Two: e carry the fix for CVE-2026-109618 and CVE-2026-109619? php.net talk say Linux distributions and LTS vendors collect the patches in advance, so your host suppose don get patched packages ready. If your site still dey on PHP 8.1 or older, press the question well, because upstream no fix those ones.

Wetin you fit do if you no fit update today (as of 22 October 2026)

php.net talk am clear: only update be complete fix. The measures below only reduce exposure to some attack paths. Dem no make your server safe. Use dem only until you fit update.

For CVE-2026-109618, php.net say make you set memory_limit=-1 in a way wey app no fit override, like php_admin_value inside the FPM pool or Apache config. Dem also suggest low post_max_size (8M if your site no get uploads, 32M if e get), plus container or cgroup memory limit. No use RLIMIT_AS or RLIMIT_DATA, because the GitHub advisory talk say those ones make mmap() fail and push PHP into the bad code path.

For CVE-2026-109619, set session.upload_progress.enabled=0 and restart every worker. Put am for php.ini, FPM pool or server config. No depend on ini_set() or FPM .user.ini, because php.net say make the setting apply before request parsing. On PHP 8.5, php.net also list fatal_error_backtraces=0.

Example for FPM pool file like /etc/php/8.3/fpm/pool.d/www.conf:

php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M
php_admin_flag[session.upload_progress.enabled] = off

Then run sudo systemctl restart "$FPM".

Sansec, the security company wey write the PHP2Shell analysis, add two warnings. First, to turn off session upload progress alone no reach. Dem advise make you block multipart/form-data for the web server too, and that one go break file uploads, so test your checkout and admin upload pages. Second, with memory_limit=-1, one request fit use all the memory for the server. That one break the math for how many PHP-FPM workers a small VPS fit carry. Watch your memory, and put the limit back after you update.

Check these values for request wey PHP-FPM serve, no be for the command line. php -i read the CLI config, /etc/php/8.3/cli/php.ini, while FPM read /etc/php/8.3/fpm/php.ini plus the pool file.

Make the next PHP security update land by itself

Ubuntu Server docs talk say unattended-upgrades dey installed by default and dey apply security updates by default. Cloud images fit differ, so check:

apt-cache policy unattended-upgrades
cat /etc/apt/apt.conf.d/20auto-upgrades
sudo unattended-upgrade -v --dry-run

APT::Periodic::Unattended-Upgrade "1" inside 20auto-upgrades mean e go run every day. The list of origins wey e trust dey /etc/apt/apt.conf.d/50unattended-upgrades, and the logs dey /var/log/unattended-upgrades. By default that list carry Ubuntu origins like the -security pocket, no be PPAs. So if your PHP come from ppa:ondrej/php, the default setup no go install PHP update for you. The full setup dey for how to set up unattended-upgrades on Ubuntu.

Two things remain your work. Unattended upgrade install the package, but the Step 4 check still apply: confam say PHP-FPM or Apache restart. And when next CVE drop, you need fast way to know whether your server dey affected. For that one, see how to check your server for known CVEs.

FAQ

Why php -v still show 8.3.6 after I apply the PHP security update?

Ubuntu 24.04 put the fix inside im own 8.3.6 package and change only the package revision. php -v print only the upstream part, so patched and unpatched server go show the same 8.3.6. Run dpkg-query -W -f='${Version}\n' php8.3-common and compare the result with 8.3.6-0ubuntu0.24.04.13 using dpkg --compare-versions with the ge operator.

I don run apt upgrade. Why I still need to restart PHP-FPM?

The upgrade replace the file for disk, but the PHP-FPM process wey dey run still hold the old code for memory. Run sudo readlink /proc/$(systemctl show -p MainPID --value php8.3-fpm)/exe. If e end with (deleted), the old PHP still dey serve your site. Run sudo systemctl restart php8.3-fpm and check again. For mod_php, restart apache2.

My server still dey on PHP 8.1. Wetin I fit do?

The PHP project no release fixed 8.1. On Ubuntu 22.04, the security pocket get fixed php8.1 at 8.1.2-1ubuntu2.28, so sudo apt update && sudo apt upgrade plus restart go cover you. On 20.04 with php7.4, the fix come only through Ubuntu Pro. The official Docker image get no fixed 8.1 tag. If none of these fit your setup, move to supported PHP version.

My WordPress site dey on cPanel shared hosting. How I go know whether e don patch?

You no fit patch am yourself, because the host control the PHP build. Open ticket and ask which PHP build serve your site, and whether e carry the fix for CVE-2026-109618 and CVE-2026-109619. If the answer no clear, or your site still dey on PHP 8.1 or older, ask make dem move you to patched supported version.