SSD Nodes Learn Hosting plans →
Gidsen Matt ConnorDoor Matt Connor

Is de PHP op je server echt gepatcht?

Je server meldt PHP 8.3.6, het nieuws zegt 8.3.36. Zo test je met dpkg of de fix voor PHP2Shell er echt staat, en of je webserver de nieuwe code al draait.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, October 22, 2026.

Kort antwoord: is je PHP gepatcht als het nummer niet klopt?

Is de PHP op je server echt gepatcht tegen PHP2Shell als jouw Ubuntu-server 8.3.6 meldt? Overal lees je namelijk dat je naar 8.3.36 moet. Toch kan die server prima gepatcht zijn. Ubuntu houdt het versienummer van PHP zelf vast en zet de fix in de pakketrevisie, het deel achter het streepje. Je test dat met dpkg --compare-versions tegen de versie uit de beveiligingsmelding van Ubuntu. Daarna controleer je of php-fpm of Apache na de update opnieuw is gestart. Een gepatcht pakket op de schijf verandert namelijk niets aan een proces dat al in het geheugen draait.

Kom je van shared hosting, dan is dit nieuw voor je. Daar installeerde de hoster de update en herstartte hij de webserver. Op je eigen VPS (virtual private server) doe je allebei zelf. De commando's hieronder zijn geschreven voor Ubuntu 24.04 en 26.04. Voor 22.04 staan de versienummers er ook bij.

Wat is PHP2Shell, en wie loopt risico?

PHP2Shell is de naam voor twee kwetsbaarheden in PHP zelf. Ze hebben de CVE-nummers (Common Vulnerabilities and Exposures) CVE-2026-109618 en CVE-2026-109619. PHP publiceerde op 21 oktober 2026 gerepareerde releases. Beide fouten maken remote code execution mogelijk: een aanvaller kan jouw server zijn eigen code laten uitvoeren.

  • CVE-2026-109618 zit in de afhandeling van een geheugentekort. Volgens de advisory van PHP kan zo'n out-of-memory-situatie PHP onderbreken terwijl interne requestdata nog maar half is opgebouwd. De opruimcode behandelt die ongeldige data daarna als geldig.
  • CVE-2026-109619 gaat over achtergebleven toestand. Interne gegevens van een request kunnen blijven bestaan nadat het geheugen erachter is vrijgegeven. Een volgend request in dezelfde worker kan die oude gegevens gebruiken voordat ze opnieuw worden ingesteld.

PHP zegt dat elke PHP-installatie die webrequests afhandelt risico loopt. De advisory noemt PHP-FPM (FastCGI Process Manager), Apache met mod_php, php-cgi, FrankenPHP en LiteSpeed. Volgens PHP is het risico het grootst bij mod_php. Daarvoor bestaat een gedemonstreerde exploit waarbij een request zonder login de aanval start voordat er applicatiecode draait. Voor een WordPress- of Laravel-site betekent dat: een bijgewerkte plugin of een veilig framework helpt hier niet. De fout zit onder je applicatie.

Het Nationaal Cyber Security Centrum (NCSC) publiceert operationele informatie over PHP2Shell in de repository NCSC-NL/php2shell op GitHub. Ook daar staat dat de tijdelijke maatregelen geen volledige oplossing zijn.

Het PHP-project zelf (upstream) repareerde de fouten in PHP 8.5.12, 8.4.27, 8.3.36 en 8.2.35. PHP 8.2 krijgt na 31 december 2026 geen beveiligingsfixes meer. Voor PHP 7.4, 8.0 en 8.1 publiceerde het beveiligingsteam alleen kleine backports in broncode, voor wie zelf compileert. Verder levert het PHP-project voor 8.1 en ouder geen updates. Voor die versies ben je dus afhankelijk van je distributie.

Waarom Ubuntu 8.3.6 houdt en toch gepatcht is

Een pakketversie op Debian en Ubuntu heeft de vorm [epoch:]upstream-versie[-revisie]. De handleiding deb-version noemt de upstream-versie het hoofddeel van het versienummer. De revisie is de versie van het pakket dat op die upstream-versie is gebouwd. dpkg splitst de string bij het laatste streepje.

Neem de gerepareerde build voor Ubuntu 24.04: 8.3.6-0ubuntu0.24.04.13. Het upstream-deel is 8.3.6. De revisie is 0ubuntu0.24.04.13. Ubuntu is dus niet naar PHP 8.3.36 overgestapt. Ubuntu heeft de fix in zijn eigen 8.3.6-build gezet en alleen de revisie verhoogd. Dat heet een backport. Wie alleen naar het getal 8.3.6 kijkt, ziet de fix dus niet. Kijk naar de hele string.

Ubuntu geeft beide CVE's de prioriteit Critical. Volgens de CVE-pagina's van Ubuntu, gelezen op 23 oktober 2026, zit de fix in deze 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, alleen met Ubuntu Pro

De eerste vier staan in USN-8948-1 (USN: Ubuntu Security Notice). Die melding noemt de binaire pakketten libapache2-mod-php8.x, php8.x-cgi, php8.x-cli en php8.x-fpm. Let op 22.04: het PHP-project ondersteunt 8.1 niet meer, maar Ubuntu heeft zijn 8.1-build wel gerepareerd. Daar ben je dus beter af met het distropakket dan met een zelfgebouwde 8.1.

Debian laat zien dat er geen vaste regel is voor het upstream-deel. In de security tracker van Debian staat php8.2 voor Debian 12 (bookworm) als kwetsbaar in 8.2.32-1~deb12u1 en als gerepareerd in 8.2.35-1~deb12u1 uit bookworm-security. Hier schoof het upstream-nummer dus wel mee, van 8.2.32 naar 8.2.35. Omdat dpkg bij het laatste streepje splitst, is de revisie hier 1~deb12u1. Het stuk ~deb12u1 is alleen een achtervoegsel binnen die revisie. Volgens deb-version sorteert de tilde vóór alles, zodat 8.2.35-1~deb12u1 lager uitkomt dan 8.2.35-1. Hoe de Debian-releases zich tot elkaar verhouden, lees je in het verschil tussen Debian stable, testing en unstable op een server. De les blijft gelijk: geen enkel los getal vertelt het je. Vergelijk de hele string met de melding van jouw eigen distributie.

Dit geldt voor veel meer dan PHP. Ubuntu repareerde CVE-2026-106587 in OpenSSH op 24.04 in 1:9.6p1-3ubuntu13.20. De 1: is de epoch. De upstream-versie blijft 9.6p1 en de fix zit in de revisie. Voor OpenSSL en nginx werk je op dezelfde manier: open de CVE-pagina van Ubuntu, neem de fixversie voor jouw release en vergelijk. Wil je dat voor alle pakketten tegelijk doen, lees dan hoe je je server op bekende CVE's controleert.

Stap 1: welke PHP-build staat er op je server?

Draait je site al, sla dan de installatieregel over. Op een kale server installeer je eerst de PHP van de distributie. De metapakketten php-cli en php-fpm installeren de PHP-versie van jouw release: php8.3 op 24.04 en php8.5 op 26.04.

sudo apt update
sudo apt install -y php-cli php-fpm
php -v
dpkg-query -W 'php8*'

Kijk wat php -v op jouw server toont: alleen het upstream-nummer, of ook de revisie erachter. Dat getal is niet de test. dpkg-query -W geeft per regel de pakketnaam en de geïnstalleerde versie, gescheiden door een tab. Die volledige versie is wat telt.

Controleer ook waar het pakket vandaan komt. Een build uit een PPA (Personal Package Archive) of uit een controlepaneel heeft andere nummers. Dan gelden de versies uit de USN niet.

apt-cache policy php8.3-fpm

Op 26.04 vervang je php8.3-fpm door php8.5-fpm. De regel met *** is de versie die nu geïnstalleerd is, met daaronder de bron.

Stap 2: de echte test met dpkg --compare-versions

Vergelijk de geïnstalleerde versie met de fixversie uit de USN. dpkg --compare-versions vergelijkt twee versiestrings volgens de regels van dpkg. Het geeft exitcode 0 als de voorwaarde klopt en 1 als die niet klopt. Gebruik de operatoren lt, le, eq, ne, ge of gt. De oude operatoren < en > zijn volgens de handleiding verouderd, omdat hun betekenis verwarrend is.

. /etc/os-release
case "$VERSION_ID" in
  24.04) pkg=php8.3-fpm; fixed=8.3.6-0ubuntu0.24.04.13 ;;
  26.04) pkg=php8.5-fpm; fixed=8.5.4-0ubuntu1.5 ;;
  22.04) pkg=php8.1-fpm; fixed=8.1.2-1ubuntu2.28 ;;
esac
installed=$(dpkg-query -W -f='${Version}' "$pkg")
echo "$pkg geinstalleerd: $installed, gerepareerd vanaf: $fixed"
if dpkg --compare-versions "$installed" ge "$fixed"; then
  echo "GEPATCHT"
else
  echo "NIET GEPATCHT"
fi

Gebruik ge (groter dan of gelijk aan) en geen gelijkheid. Een latere beveiligingsupdate verhoogt de revisie opnieuw, en die build bevat de PHP2Shell-fix ook. Zie je NIET GEPATCHT, werk dan bij met sudo apt update && sudo apt upgrade. Dat upgradecommando noemt Ubuntu in zijn blogpost over PHP2Shell. Draai de test daarna nog een keer.

Gebruik je Apache met mod_php, test dan ook libapache2-mod-php8.3 (of libapache2-mod-php8.5 op 26.04). Zet die naam in pkg en draai de laatste zeven regels opnieuw. Op 26.10 haal je de fixversie van de CVE-pagina en vul je pkg en fixed zelf in.

Stap 3: staan de CVE-nummers in de changelog?

De versievergelijking is het bewijs. De changelog van het pakket is een tweede controle die je met eigen ogen kunt lezen. De variabele $pkg komt uit stap 2, dus gebruik dezelfde terminal.

doc="/usr/share/doc/$pkg/changelog.Debian.gz"
if [ -e "$doc" ]; then
  zgrep -n 'CVE-2026-10961[89]' "$doc"
else
  apt-get changelog "$pkg" | grep -n 'CVE-2026-10961[89]'
fi

Het blok leest eerst de changelog die met het pakket is meegekomen. Minimale Ubuntu-images laten /usr/share/doc soms weg. Ontbreekt het bestand daardoor, dan valt het blok terug op apt-get changelog. Dat commando downloadt de changelog en toont standaard die van de geïnstalleerde versie. Daarvoor heb je dus een netwerkverbinding nodig. Kort na een beveiligingsupdate kan die download mislukken met 404 Not Found, omdat changelogs.ubuntu.com de nieuwe build dan nog niet heeft. Zie je beide CVE-nummers, dan bevestigt de changelog wat stap 2 al zei. Zie je ze niet, vertrouw dan op stap 2 en kijk of je de juiste pakketnaam gebruikt.

Gepatcht op de schijf is nog niet gepatcht in het geheugen

Hier gaat het op veel servers mis. In zijn blogpost over PHP2Shell schrijft Ubuntu: "The application that uses the PHP interpreter would likely need to be restarted." Een draaiend proces gebruikt de code die het bij het starten heeft geladen. apt vervangt de bestanden op de schijf. Een php-fpm-master die vorige week is gestart, draait dan nog steeds de oude code. Dat geldt ook voor Apache met mod_php, want daar zit PHP in het Apache-proces zelf.

Gebruik je nginx of Apache met php-fpm, herstart dan php-fpm:

sudo systemctl restart "$pkg"
systemctl is-active "$pkg"

systemctl is-active moet active tonen. Met nginx herstart je alleen php-fpm. nginx zelf bevat geen PHP, het stuurt de requests door naar php-fpm. Al je pools uit /etc/php/8.3/fpm/pool.d/ horen bij dezelfde service, dus één herstart neemt ze allemaal mee. Wil je die pools meteen nakijken, lees dan hoe je php-fpm-pools dimensioneert op een kleine VPS.

Gebruik je Apache met mod_php, herstart dan Apache. Dit is het commando uit de blogpost van Ubuntu:

sudo systemctl restart apache2

Weet je niet zeker of Apache draait, gebruik dan sudo systemctl try-restart apache2. Dat herstart een unit alleen als hij al draait. restart start een gestopte unit ook, en dat wil je niet als Apache bewust uit staat. Twijfel je welke processen nog oude code gebruiken, dan is sudo reboot de grove maar zekere weg. Ubuntu noemt die optie ook.

Draait de service al sinds de upgrade?

Een vergeten herstart zie je niet aan de website. Vergelijk daarom twee tijden: wanneer de service actief werd, en wanneer dpkg het pakket installeerde.

systemctl show -p ActiveEnterTimestamp --value "$pkg"
grep -E "(install|upgrade) $pkg" /var/log/dpkg.log | tail -n 1

ActiveEnterTimestamp is volgens de systemd-documentatie het moment waarop de unit voor het laatst van activating naar active ging. Is die overgang in deze boot nog niet gebeurd, dan is de waarde leeg of nul. /var/log/dpkg.log is het standaardlogbestand van dpkg. De tweede regel toont de laatste keer dat dpkg dit pakket installeerde of bijwerkte.

De tijd van de service moet later liggen dan de tijd in de dpkg-regel. Ligt hij eerder, dan draait de service nog met de code van vóór de update. Herstart hem dan. Geeft grep niets terug, dan staat de update mogelijk in een ouder logbestand. ls /var/log/dpkg.log* laat zien welke er zijn.

Is needrestart geïnstalleerd, dan kun je dat ook laten kijken. Dat programma controleert welke daemons na een bibliotheekupdate opnieuw moeten starten.

sudo needrestart -r l

-r l betekent: alleen een lijst tonen, niets herstarten. Lees wat het op jouw server meldt. Staat je php-fpm-service of apache2 in de lijst, herstart die dan. Staat hij er niet in, dan blijft de tijdvergelijking hierboven je bewijs. Gebruik needrestart als hulpmiddel. Het echte bewijs zijn de twee tijden.

Automatische updates installeren het pakket, maar herstarten ze ook?

De Ubuntu Server-documentatie zegt dat Ubuntu Server standaard beveiligingsupdates automatisch installeert. Staat dat bij jou aan, dan kan het gepatchte pakket er al staan zonder dat je iets deed. Dat is de helft van het werk. Volgens de handleiding van needrestart valt de interactieve modus terug op alleen een lijst tonen als needrestart niet-interactief draait, zoals onder unattended-upgrades. Ga er dus niet van uit dat de automatische update je PHP-service ook heeft herstart. Controleer het met de tijden uit de vorige stap. Hoe je de automatische updates zelf instelt en nakijkt, staat in unattended-upgrades instellen en controleren op Ubuntu.

Ubuntu 20.04 of ouder: de fix zit achter Ubuntu Pro

Voor oudere releases staat de fix in USN-8948-2. Ubuntu 20.04 krijgt php7.4 7.4.3-4ubuntu2.29+esm5 en Ubuntu 18.04 krijgt php7.2 7.2.24-0ubuntu0.18.04.17+esm14, allebei via Ubuntu Pro. Voor 16.04 en 14.04 heb je Ubuntu Pro met de Legacy Support-add-on nodig. Het achtervoegsel +esm in de versie laat zien dat de build uit ESM (Expanded Security Maintenance) komt. Dat is de dienst van Ubuntu Pro voor releases buiten de standaardondersteuning. Ubuntu 26.10, 26.04, 24.04 en 22.04 krijgen de fix gewoon via de standaardondersteuning.

Over de prijs is Ubuntu niet overal even precies. De blogpost over PHP2Shell zegt dat Pro gratis is voor maximaal 5 machines, of 50 voor communityleden. De Pro-pagina zelf zegt "free for personal use on up to 5 physical machines". Draai je een zakelijke VPS, lees dan eerst de voorwaarden op ubuntu.com/pro voordat je ervan uitgaat dat het gratis is. Wat Pro precies aanzet, lees je in Ubuntu Pro op een server uitgelegd.

Zie Pro als noodoplossing voor een server die nog op 20.04 staat. PHP 7.4 krijgt van het PHP-project zelf al lang geen updates meer. Een upgrade naar een LTS-release met standaardondersteuning haalt je uit die afhankelijkheid. Het upgradepad weg van Ubuntu 20.04 laat zien hoe.

PHP uit een PPA, een controlepaneel, of Rocky en Alma

Komt je PHP uit de PPA van Ondřej Surý (ppa:ondrej/php), dan gelden de versies uit de USN niet. Volgens de Launchpad-pagina wordt die PPA samengevoegd met packages.sury.org. Voor Ubuntu 26.04 is packages.sury.org de officiële bron. De versienummers werken daar anders. Kijk in de meldingen van die bron welke build de fix bevat. Vergelijk daarna met dpkg --compare-versions zoals in stap 2.

Hetzelfde geldt voor PHP-builds van controlepanelen zoals Plesk, DirectAdmin en cPanel met EasyApache. Die panelen leveren hun eigen PHP naast of in plaats van de distributie-PHP. Zoek de beveiligingsmelding van die leverancier op. Controleer daarna ook daar of de PHP-processen opnieuw zijn gestart.

Op Rocky Linux en AlmaLinux werkt de controle via RPM. rpm -q --changelog toont de wijzigingsinformatie van een geïnstalleerd pakket. Zoek daarin naar de twee CVE-nummers en vergelijk de versie met de beveiligingsmelding van je distributie. Ook daar zegt een upstream-nummer dat achterloopt op zich niets.

Is een WAF genoeg tegen PHP2Shell?

Nee. PHP schrijft in elke release-aankondiging: "There are no complete mitigations, updating is the only safe choice." De advisory voegt toe dat de tijdelijke maatregelen de blootstelling aan bepaalde aanvalspaden verkleinen, maar een installatie niet veilig maken. Een WAF (web application firewall) kan een bekend aanvalspatroon tegenhouden. De kwetsbare code blijft dan gewoon op je server draaien. Een beveiligingsplugin in WordPress helpt bij mod_php al helemaal niet. Zo'n plugin is applicatiecode, en volgens PHP start de aanval daar voordat er applicatiecode draait. Werk PHP bij en herstart de service die het gebruikt.

FAQ

Mijn server toont PHP 8.3.6. Ben ik kwetsbaar voor PHP2Shell?

Niet per se. Ubuntu 24.04 houdt het upstream-nummer 8.3.6 vast en zet de fix in de pakketrevisie. De gerepareerde build is 8.3.6-0ubuntu0.24.04.13. Haal de volledige versie op met dpkg-query -W -f='${Version}' php8.3-fpm en vergelijk met dpkg --compare-versions <versie> ge 8.3.6-0ubuntu0.24.04.13. Exitcode 0 betekent dat het pakket gepatcht is. Daarna moet de service nog opnieuw gestart zijn.

Moet ik na de PHP-update php-fpm of Apache herstarten?

Ja. Ubuntu schrijft dat de toepassing die PHP gebruikt waarschijnlijk opnieuw moet starten. Een draaiend proces houdt de code die het bij het starten laadde. Herstart php-fpm met sudo systemctl restart php8.3-fpm (php8.5-fpm op 26.04), of Apache met sudo systemctl restart apache2 als je mod_php gebruikt. Vergelijk daarna systemctl show -p ActiveEnterTimestamp --value php8.3-fpm met de laatste regel voor dat pakket in /var/log/dpkg.log. De service moet later zijn gestart.

Ik draai nog Ubuntu 20.04. Hoe krijg ik de fix voor PHP 7.4?

Ubuntu 20.04 krijgt de fix in php7.4 7.4.3-4ubuntu2.29+esm5, maar alleen via Ubuntu Pro met ESM (Expanded Security Maintenance). De blogpost van Ubuntu noemt Pro gratis voor maximaal 5 machines. De Pro-pagina beperkt dat tot persoonlijk gebruik op fysieke machines, dus lees de voorwaarden als je server zakelijk is. Plan daarnaast een upgrade naar een LTS-release met standaardondersteuning.

Werkt dezelfde versiecontrole voor OpenSSH, OpenSSL en nginx?

Ja. Ook daar kan Ubuntu de fix in de bestaande upstream-versie zetten en alleen de revisie verhogen. OpenSSH op 24.04 is een voorbeeld: CVE-2026-106587 is gerepareerd in 1:9.6p1-3ubuntu13.20, terwijl de upstream-versie 9.6p1 blijft. Zoek de CVE op ubuntu.com op, neem de fixversie voor jouw release en vergelijk die met dpkg --compare-versions. Herstart daarna de service die het pakket gebruikt.