PHP2Shell: twee kritieke lekken in PHP, en wat je vandaag moet doen
· Bijgewerkt · 31 min lezen · 6.105 woorden · 73 bronnen
Het PHP-securityteam heeft op woensdag 21 oktober 2026 PHP 8.5.12, 8.4.27, 8.3.36 en 8.2.35 uitgebracht. De aankondigingen gingen rond 15.00 uur Nederlandse tijd online, een uur eerder dan gepland. Die versies dichten twee kritieke kwetsbaarheden, allebei CVSS v4.0 9.2, waarmee een aanvaller zonder in te loggen code op je server kan uitvoeren. In het nieuws heten ze PHP2Shell. Draait jouw website, webshop of applicatie op PHP, dan update je vandaag en niet volgende week.
Addendum 22 oktober: is de patch wel compleet?
Securityonderzoekers pluizen de patches van woensdag uit, en twee van hen claimen nieuwe problemen, meldt Tweakers. Mijn conclusie: update nog steeds naar de versies hieronder, want die dichten de twee CVE's. Reken er alleen niet op dat dit de laatste PHP-update van deze maand is.
- Er staat nu een werkende aanval openbaar. Onderzoeker Nicolas Krassas publiceerde op GitHub een aanval zonder inloggen op PHP 8.5.11, getest in een labopstelling met niet-standaard instellingen, zoals
display_errorsaan en één Apache-worker. Hij schrijft er zelf bij dat dit niet bewijst dat de aanval op elke installatie werkt. Wie nog niet heeft gepatcht, loopt nu wel meer risico dan woensdag. - Krassas schreef woensdagavond op X dat de patch in 8.5.12 "incomplete" is, met de toevoeging dat dit nog "further validation" nodig heeft. In zijn onderzoek werken beide CVE-aanvallen op 8.5.12 niet meer, maar blijven drie andere routes over. De eerste is een geheugenfout in
unserialize()die hij in mei al publiceerde. De tweede werkt alleen als een applicatie sessies met twee verschillendesession.serialize_handler-instellingen leest. Bij de derde komt aanvallersdata letterlijk in sessiebestanden terecht via upload progress, en die is alleen bruikbaar als je applicatie zelf ook een lek heeft waarmee een aanvaller een bestand kan laten includen. Krassas heeft dit niet afgestemd met het PHP-securityteam. Op Reddit en LinkedIn wordt over de geldigheid van zijn claim gediscussieerd. - Onderzoeker Elise Amber Katze vond woensdag een derde bug, een zogenoemde double free, die volgens haar ook op 8.5.12 werkt. Zij meldde die bij PHP. PHP-kernontwikkelaar Ilija Tovilo noemt het volgens Tweakers een andere geheugenbug, die "op geen enkele manier urgent" is. Canonical vroeg PHP ernaar en kreeg te horen dat het "unrelated and not a real issue" is, schreef Aaron Rainbolt op de mailinglijst oss-security. Hij had dat uit de tweede hand en vroeg PHP het te bevestigen.
Krassas' onderzoek maakt ook twee van de tijdelijke maatregelen verderop zwakker:
- Met tienduizenden korte headers laat hij een ongepatchte PHP ongeveer 52 keer zoveel geheugen gebruiken als het request groot is. Een request dat binnen een
post_max_sizevan 8M past, kan het geheugen zo toch laten vollopen. Volgens hem sluit de patch die route. - PHP accepteert
Content-Type: multipart/form-data, boundary=...met een komma op de plek van de gebruikelijke puntkomma. WAF-regels die op de puntkomma zoeken, missen zo'n request.
Wat ik zelf aanraad, naast patchen: zet session.upload_progress.enabled=0 en laat dat ook na de update zo, als je applicatie geen uploadvoortgang toont. Standaard staat die instelling aan. Daarmee valt de derde route van Krassas weg, en de meeste sites merken er niets van. Gebruik verder één session.serialize_handler voor de hele applicatie, ingesteld in php.ini of de FPM-pool, en niet per map of per script.
Hoe groot is dit?
PHP zit onder WordPress, WooCommerce, Joomla, Drupal, TYPO3, Magento, Shopware, PrestaShop en onder frameworks als Laravel, Symfony, CodeIgniter en CakePHP. Het lek zit in PHP zelf, dus elk van die platforms is geraakt, ongeacht hoe goed de applicatie zelf is gebouwd. Een proof-of-concept-video die rondging liet volgens Tweakers zien hoe een aanvaller de login van Joomla en WordPress omzeilt. Het eerste lek werd op 11 augustus gemeld door securitybedrijf Calif en dezelfde dag, los daarvan, door OpenAI. Wiz meldde op 24 augustus nog meer aanvalsroutes, schrijft de PHP Foundation. Wiz, dat AI-tools gebruikte, zei tegen Reuters dat ze "meer dan tien jaar onopgemerkt" bleven. De PHP Foundation erkent dat de fix maanden op zich liet wachten, en noemt die vertraging "a structural failure".
In Nederland gingen woensdag tientallen bekende sites en diensten uit voorzorg op zwart. Volgens het AD, de NOS, NU.nl en het ANP ging het onder meer om:
- DigiD, MijnOverheid, de Tweede Kamer, delen van UWV en zelfs de site van het NCSC
- zeker 13 van de 25 veiligheidsregio's, de Unie van Waterschappen en NotuBiz, met de raadsinformatie van ruim 100 gemeenten, provincies en waterschappen
- ziekenhuizen: de sites van onder meer het Jeroen Bosch Ziekenhuis, Haaglanden MC en St. Antonius waren niet bereikbaar, en bij Bravis stond: "Vanwege de PHP2Shell-kwetsbaarheid hebben wij onze systemen uit voorzorg tijdelijk in onderhoudsmodus gezet"
- de Odido-merken Ben en Simpel, Eneco-dochter Agro Energy, Havenbedrijf Rotterdam, de Schiphol-app, supermarkt Hoogvliet en delen van het onderwijsnetwerk van SURF
- Maastricht UMC+, Thuisarts.nl, Medimo, waarmee thuiszorg en verpleeghuizen medicatie verstrekken, en Stichting Ambulance Wens, die niet meer bij de planning voor de wensen van de volgende dag kon
- RTL Nieuws, DPG Media-titels als Tweakers, AutoWeek en vtwonen, Pathé Thuis en het uploadsysteem van NPO Start en NPO Luister. Tweakers meldde zelf: "We hebben onze systemen uit voorzorg offline gehaald vanwege kritieke PHP2Shell-kwetsbaarheden."
- de ANWB, Duinrell, TicketSwap en kinderopvangorganisaties als Humankind, KION en Basker
- de KNVB, goede doelen als KWF en Amnesty, en de sites van onder meer VVD, CDA, BBB en Partij voor de Dieren
- hostingprovider Mijndomein, die om 13.35 uur honderdduizenden websites offline haalde, waaronder Managed WordPress en Managed WooCommerce
Woensdagavond waren veel sites weer online. Volgens de NOS kwamen Tweakers en RTL rond 17.00 uur terug, MijnOverheid rond 18.10 uur en DigiD rond 20.30 uur.
Ook buiten Nederland gingen sites uit de lucht. De Vlaamse minister-president Matthias Diependaele liet alle Vlaamse overheidswebsites offline halen, en ook in Finland, Japan en Frankrijk gingen sites op zwart. NU.nl en het AD bleven zelf gewoon online: hun nieuwssites draaien niet op PHP.
Aanvalspogingen zijn er al. Cloudflare-CTO Dane Knecht schreef woensdagochtend om 09.43 uur: "We are seeing early attacks emerging and are updating mitigations as new vectors show up." Of er ook al ergens is ingebroken, is niet bevestigd. De PHP Foundation zei tegen het ANP geen indicatie van actief misbruik te hebben, en het NCSC had woensdag nog geen actief misbruik gezien. Ook de Amerikaanse CISA ziet volgens de NOS geen actief misbruik, en op 22 oktober stonden de lekken niet in de lijst van actief misbruikte kwetsbaarheden van CISA. Het NCSC waarschuwde wel voor "een zeer hoog risico op volledige overname van het systeem". NCSC-directeur Corine Schipper-Derkse noemde het tegen het AD "geen aanval", maar een weeffout waarvan "het potentiële gevaar heel groot" is.
Wat er aan de hand is
- CVE-2026-109618, RCE via OOM corruption. Raakt PHP zonder geheugen terwijl interne requestdata nog maar half is opgebouwd, dan kan de opruimstap aan het eind van het request die halve data als geldig behandelen.
- CVE-2026-109619, RCE via stale global state. Interne state van een request kan blijven bestaan nadat het geheugen erachter is vrijgegeven. Een volgend request op dezelfde worker kan die state dan gebruiken voordat die opnieuw is opgezet.
Elke PHP-installatie die webrequests afhandelt is geraakt: PHP-FPM, Apache met mod_php, php-cgi, FrankenPHP en LiteSpeed. Het risico is het grootst bij mod_php. Daar bestaat een werkende exploit die toeslaat voordat er één regel applicatiecode draait.
Naar welke PHP-versie
- PHP 8.5 naar 8.5.12
- PHP 8.4 naar 8.4.27
- PHP 8.3 naar 8.3.36
- PHP 8.2 naar 8.2.35
Houd er rekening mee dat er nog een update kan volgen. Het NCSC sluit volgens NU.nl niet uit dat er later een nieuwe update komt, mocht de eerste niet alle problemen oplossen.
Check per server en per container wat er draait met php -v. Vergeet CI-runners, cronservers en managed hosting niet. Herstart na de update PHP-FPM of je webserver, als je pakketbeheerder dat niet zelf deed. php -v toont dan al de nieuwe versie, terwijl de draaiende workers nog de oude code gebruiken. Kies je nu een nieuwe versie, neem dan 8.3 of hoger: PHP 8.2 is op 31 december 2026 end-of-life.
PHP 8.1 en ouder krijgen geen release meer. Het securityteam heeft wel minimale source-backports gepubliceerd voor 7.4, 8.0 en 8.1, voor wie zelf PHP bouwt. Verderop staat wat je nog meer kunt doen als je op een oude versie vastzit.
Upgradepad per Linux-distributie
Linux-distributies kregen de patches vooraf. De meeste hebben nu fixes voor hun ondersteunde PHP-versies, maar oudere Alpine-releases, uitgefaseerde streams op RHEL en Rocky en de ARM-builds van Surý liepen nog achter. Hieronder de stand van donderdag 22 oktober rond 10.45 uur. Controleer de securitytracker van je distributie voor de actuele status.
Ubuntu
- 26.04 heeft PHP 8.5, 24.04 heeft PHP 8.3 en 22.04 heeft PHP 8.1. Ubuntu patcht die versies zelf. Om 15.56 uur verscheen USN-8948-1 met de gepatchte versies: 8.1.2-1ubuntu2.28 voor 22.04, 8.3.6-0ubuntu0.24.04.13 voor 24.04, 8.5.4-0ubuntu1.5 voor 26.04 en 8.5.9-0ubuntu2.1 voor 26.10. De securitybron van Ubuntu levert die versies inmiddels. Controleer met
apt-cache policy php8.3-fpm(pas de versie aan) dat je ze hebt, en metapt changelog php8.3-cli | grep 109618dat de fix erin zit. - 20.04 (PHP 7.4) en 18.04 (PHP 7.2) krijgen alleen nog updates via Ubuntu Pro. Voor persoonlijk gebruik is dat gratis tot vijf machines. De fix staat in USN-8948-2, die via de betaalde Legacy-add-on ook 16.04 en 14.04 dekt.
- Gebruik je de pakketten van Ondřej Surý, dan hebben
packages.sury.orgen de PPAppa:ondrej/php(alleen 22.04 en 24.04) op amd64 PHP 8.2.35 tot en met 8.5.12. Op ARM heeft alleen de PPA ze. Verderop staat waarom je daarpackages.sury.orgnu niet moet toevoegen. - Upgradepad: naar 24.04 (PHP 8.3) of 26.04 (PHP 8.5).
Debian
- 13 trixie heeft PHP 8.4, 12 bookworm heeft PHP 8.2 en 11 bullseye heeft PHP 7.4.
- Debian 12 zit sinds juni 2026 in LTS. Debian 11 viel op 31 augustus 2026 uit de gratis LTS. Daarna bestaat alleen nog de betaalde ELTS van Freexian, net als voor Debian 10.
- Debian 13: php8.4 8.4.27-1~deb13u1 in
trixie-security(DSA-6574-1). Debian 12: php8.2 8.2.35-1~deb12u1 inbookworm-security(DLA-4848-1). Debian 11: php7.4 7.4.33-1+deb11u14 via Freexian ELTS (ELA-1853-1). Oppackages.sury.orgstaan 8.2.35 tot en met 8.5.12 voor Debian 11, 12 en 13, maar op ARM (arm64) nog niet. - Upgradepad: naar Debian 13 (PHP 8.4). Debian 12 geeft je PHP 8.2, en die versie stopt bij PHP zelf eind dit jaar.
CentOS, RHEL, AlmaLinux en Rocky Linux
- CentOS 7 is sinds 30 juni 2024 end-of-life, CentOS Stream 8 sinds 31 mei 2024 en CentOS Linux 8 al sinds eind 2021. Daar komt geen update meer voor.
- RHEL, AlmaLinux en Rocky 8 bieden PHP 7.4 en 8.2, versie 9 biedt 8.0 standaard met 8.2 en 8.3 als stream, en versie 10 biedt 8.3 en 8.4.
- Red Hat bracht op 21 oktober tussen 17.53 en 22.36 uur RHSA's uit voor RHEL 8 (php:7.4 en php:8.2), 9 (php, php:8.2 en php:8.3) en 10 (php en php8.4). Rocky Linux volgde in de nacht naar 22 oktober. Alleen PHP 8.2 op Rocky 8 ontbrak donderdagochtend nog. AlmaLinux bracht dezelfde dag eigen gepatchte pakketten uit voor elke PHP-stream op 8, 9 en 10, ook voor oude streams die Red Hat niet meer ondersteunt. Die houden soms hun oude versienummer, dus controleer met
rpm -q --changelog php-common | grep 109618(bij PHP 8.4 op versie 10:php8.4-common). De repository van Remi (rpms.remirepo.net) heeft 8.2.35 tot en met 8.5.12 voor versie 8, 9 en 10. PHP schreef in het advisory eerst dat Remi die dag geen update zou krijgen, maar haalde die zin om 16.18 uur weg. - Upgradepad vanaf CentOS 7: in-place naar AlmaLinux 8 met ELevate en daarna verder, of een schone installatie van AlmaLinux of Rocky 9 of 10 (PHP 8.3 of 8.4). Voor een applicatieserver is die schone installatie meestal de rustigste route.
Docker, FrankenPHP en hostingpanelen
- De officiële Docker-images hebben sinds de nacht van 21 op 22 oktober tags voor 8.5.12, 8.4.27, 8.3.36 en 8.2.35. Rebuild met
docker build --pullen herstart je containers. - Bij FrankenPHP zit PHP in de image of binary zelf. Daar heb je een nieuwe FrankenPHP-build nodig, en die is er: FrankenPHP 1.13.2 van 21 oktober.
- Plesk (PHP 8.2 tot en met 8.5), cPanel (EasyApache 4 versie 25.91) en CloudLinux (alt-php en ea-php) brachten op 21 en 22 oktober gepatchte pakketten uit. Draai de update van je panel en herstart PHP-FPM en Apache. Mijndomein liet woensdag aan het AD weten te wachten op de pakketten van Plesk.
Zo patch je vandaag, met en zonder package manager
Stand van donderdag 22 oktober rond 10.45 uur. In de voorbeelden staat PHP 8.4. Vervang 8.4 door jouw versie.
Debian en Ubuntu (apt): via de PPA of packages.sury.org
Ondřej Surý verspreidt PHP via twee bronnen: de bekende PPA (ppa:ondrej/php, alleen voor Ubuntu 22.04 en 24.04) en zijn eigen pakketbron packages.sury.org. Volgens de PPA zelf gaat die op termijn op in packages.sury.org. Op gewone servers (amd64) hebben beide bronnen PHP 8.2.35, 8.3.36, 8.4.27 en 8.5.12. Gebruik je de PPA al, dan volstaat sudo apt-get update && sudo apt-get upgrade.
Op ARM-servers (arm64) heeft op dit moment alleen de PPA de gepatchte versies. packages.sury.org levert daar nog 8.2.34, 8.3.35, 8.4.26 en 8.5.11. Voeg packages.sury.org op ARM dus nu niet toe. Draai je daar de PHP van Ubuntu zelf, dan word je er zelfs kwetsbaarder van. Ubuntu heeft zijn eigen PHP al gepatcht, maar de ongepatchte versie van packages.sury.org heeft een hoger versienummer, dus apt ruilt de veilige versie in voor de lekke. Op een testserver met Ubuntu 24.04 (arm64) werd de gepatchte 8.3.6-0ubuntu0.24.04.13 zo vervangen door 8.3.35.
Stap je op amd64 over naar packages.sury.org, gebruik dan één van de twee bronnen, niet allebei. Anders kiest apt per pakket de bron met het hoogste versienummer, en dat kan zomaar de andere zijn. Heb je de PPA, haal die dan eerst weg:
sudo add-apt-repository --remove ppa:ondrej/php
Voeg daarna packages.sury.org toe, zoals de README van de bron het voorschrijft, en upgrade alleen de PHP-pakketten die je al hebt:
sudo apt-get update
sudo apt-get -y install lsb-release ca-certificates curl
sudo curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
echo "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt-get update
sudo apt-get install --only-upgrade $(dpkg-query -W -f='${db:Status-Abbrev}${binary:Package}\n' 'php8.4*' | awk '$1=="ii"{print $2}')
sudo systemctl restart php8.4-fpm
De dpkg-query-regel pakt precies de PHP-pakketten die geïnstalleerd zijn. Een wildcard als 'php8.4-*' direct in apt-get breekt af op virtuele pakketnamen. Gebruik je mod_php, herstart dan Apache in plaats van PHP-FPM. Controleer daarna met php -v en apt-cache policy php8.4-fpm welke versie draait en uit welke bron die komt. Ik heb deze stappen getest op een schone Ubuntu 24.04 (amd64): PHP 8.3.6 ging naar 8.3.36.
RHEL, AlmaLinux en Rocky Linux (dnf/yum)
Red Hat, AlmaLinux en Rocky hebben gepatchte pakketten voor hun ondersteunde streams, zie hierboven. Remi heeft alle vier de gepatchte versies, 8.2.35, 8.3.36, 8.4.27 en 8.5.12, voor versie 8, 9 en 10. Gebruik je Remi al, dan volstaat sudo dnf upgrade 'php*'. Wil je Remi toevoegen, volg dan de configuratiewizard van Remi voor jouw versie. Gebruik je alleen de pakketten van je distributie, draai dan ook sudo dnf upgrade 'php*' en controleer daarna met rpm -q --changelog php-common | grep 109618 dat de fix erin zit. Op versie 10 met PHP 8.4 heet dat pakket php8.4-common. Vertrouw hier niet op php -v. Red Hat en AlmaLinux zetten de fix soms in een bestaande versie, zodat je bijvoorbeeld nog 8.0.30 of 8.2.33 ziet. CentOS 7 met yum krijgt helemaal geen update meer.
Alpine (apk)
Alpine 3.24 en edge hebben inmiddels php83 8.3.36, php84 8.4.27 en php85 8.5.12. Op 3.23 was op 22 oktober alleen php83 bijgewerkt, php84 en php85 nog niet. Op 3.22 en ouder is niets bijgewerkt. Draai apk update && apk upgrade en controleer met php84 -v.
Docker
De officiële php-images hebben sinds de nacht van 21 op 22 oktober tags voor 8.5.12, 8.4.27, 8.3.36 en 8.2.35. Ook tags als 8.4-fpm wijzen er nu naar. Haal de nieuwe images op, bouw je eigen images opnieuw op de nieuwe basis en herstart de containers:
docker compose pull --ignore-buildable
docker compose build --pull
docker compose up -d
docker compose exec app php -v
Vervang app door de naam van je PHP-service. De eerste regel is nodig voor services die een php-image direct gebruiken, want build --pull slaat die over.
Zelf bouwen uit de broncode
De broncode van alle vier de gepatchte versies staat op php.net, met checksum en handtekening. Dit is de route als je geen bijgewerkt pakket hebt en niet kunt wachten. Neem dezelfde configure-opties over als je huidige build, anders mis je extensies:
php -i | grep 'Configure Command'
curl -fsSLO https://www.php.net/distributions/php-8.4.27.tar.xz
echo "dcf93923b0e38e0d5252b25b796520b5a47761a08b3488b6d0b5d1115764d3f0 php-8.4.27.tar.xz" | sha256sum -c
tar xf php-8.4.27.tar.xz && cd php-8.4.27
./configure # met de opties uit de eerste regel
make -j"$(nproc)"
sudo make install
Voor PHP 7.4, 8.0 en 8.1 bouw je uit de backport-branch van het securityteam, bijvoorbeeld voor 8.1:
git clone --depth 1 --branch PHP-8.1-CVE-2026-109618-109619 https://github.com/php/php-src.git
cd php-src && ./buildconf --force
Daarna gaat het verder zoals hierboven met ./configure, make en make install. Een build uit git heeft ook autoconf, bison en re2c nodig, en meldt zich daarna nog gewoon als 8.1.34. Aan php -v zie je de fix dus niet. Een eigen build installeer je standaard onder /usr/local, naast de PHP van je distributie. Let op welke binary je webserver en PHP-FPM daarna echt gebruiken.
FrankenPHP
FrankenPHP 1.13.2 kwam woensdagavond om 20.19 uur uit. De Docker-images daarvan zijn gebouwd met PHP 8.2.35, 8.3.36, 8.4.27 en 8.5.12, de losse binaries met PHP 8.5.12. De release dicht ook vier lekken in FrankenPHP zelf. Update naar 1.13.2, en lees de upgrade-notes in de release op GitHub als je de static builds gebruikt. Er is geen binary meer voor Intel-Macs, en de -gnu-binary vraagt nu glibc 2.28 of nieuwer.
Vergeet je extensies niet (PECL en PIE)
De twee lekken zitten in PHP zelf, maar extensies spelen mee. Volgens het advisory van CVE-2026-109619 houdt een worker ook "extension state" vast tussen requests, en hangt het onder meer van "the callbacks registered by that application or extension" af of een aanval werkt. Het advisory van CVE-2026-109618 zegt dat de exploit afhangt van "the PHP build, extensions, frontend behavior and allocator layout". Een lek in een specifieke extensie noemen de advisories niet.
Nu je toch bezig bent, is dit wel het moment om je extensies na te lopen. Ze hebben hun eigen releases en securityfixes, los van PHP. Denk aan redis, imagick, apcu, xdebug of swoole. Extensies die een C-bibliotheek inpakken, zoals imagick met ImageMagick, krijgen hun fixes deels via die bibliotheek.
Wat je moet doen, hangt af van je situatie:
- Je blijft op dezelfde minor-versie, bijvoorbeeld van 8.4.26 naar 8.4.27. Dan blijven je extensies werken, want een patchrelease verandert de interne API van PHP niet.
- Je stapt over naar een andere minor-versie, bijvoorbeeld van 8.1 naar 8.3, of je bouwt PHP zelf. Dan moet je elke extensie opnieuw installeren voor die versie. Vergeet je er een, dan draait PHP zonder die extensie, en dat merk je pas als je applicatie erop stukloopt. Vergelijk
php -mvoor en na, en zoek in de log van PHP-FPM naar "Unable to load dynamic library". - Extensies die je via PECL of PIE hebt geïnstalleerd, werk je zelf bij. PECL is officieel deprecated. De opvolger is PIE van de PHP Foundation.
php -m # welke extensies laden nu
pecl list # wat via PECL is geïnstalleerd
pecl list-upgrades # welke daarvan een nieuwere versie hebben
pie show # wat via PIE is geïnstalleerd
Installeer je met PIE een extensie voor een andere PHP-versie op dezelfde machine, geef die versie dan mee met --with-php-config, bijvoorbeeld pie install --with-php-config=/usr/bin/php-config8.3 vendor/extensie. Draai je pie install zonder argumenten in de map van je project, dan controleert PIE of alle extensies uit je composer.json aanwezig zijn. In Docker worden extensies die je Dockerfile met pecl install of docker-php-ext-install toevoegt opnieuw gebouwd zodra je met --pull op een nieuwe basisimage bouwt.
Wat betekent dit voor WordPress, Magento, Laravel en de rest?
De vraag is niet of je platform geraakt is, want dat is het. De vraag is hoe makkelijk je naar een gepatchte PHP-versie gaat. Dat hangt af van de versie van je platform.
Meestal een update van een middag of een dag, als je platform bij is:
- WordPress 6.9 en nieuwer draait op PHP 8.2 tot en met 8.5, en WooCommerce raadt PHP 8.3 of hoger aan. Het risico zit in oude plugins en thema's die niet met PHP 8 overweg kunnen.
- Laravel 12 (PHP 8.2 tot en met 8.5) en Laravel 13 (8.3 tot en met 8.5).
- Symfony 7.4 LTS (8.2 en hoger) en Symfony 8.1 (8.4 en hoger).
- Drupal 11 (8.3 en hoger, 8.5 vanaf 11.3) en Drupal 10.4 tot en met 10.6 (8.1 tot en met 8.4). Drupal 10 is op 9 december 2026 end-of-life.
- Joomla 5 (8.1 en hoger) en Joomla 6 (8.3 en hoger).
- TYPO3 13 en 14 (8.2 tot en met 8.5).
- Magento 2.4.6 (8.1 en 8.2), 2.4.7 (8.2 en 8.3), 2.4.8 (8.3 en 8.4) en 2.4.9 (8.5), OpenMage (8.1 tot en met 8.5), Shopware 6.6 en 6.7 (8.2 tot en met 8.4) en PrestaShop 9.
- CodeIgniter 4.7, CakePHP 5, Craft CMS 5 en Nextcloud 33 tot en met 35.
Vaak een project, omdat de stap naar PHP 8.2 of hoger eerst een upgrade of migratie van het platform vraagt:
- Magento 1 is sinds juni 2020 end-of-life. De route is OpenMage of een nieuw platform.
- Magento 2.3 en 2.4.0 tot en met 2.4.3 zijn end-of-life en draaien op PHP 7. Magento 2.4.4 en 2.4.5 draaien alleen op PHP 8.1. Eerst Magento upgraden dus.
- PrestaShop 1.7 komt niet verder dan PHP 7.4 en PrestaShop 8 niet verder dan 8.1.
- Drupal 7, Joomla 3 en 4, CakePHP 3, Yii 1.1, Zend Framework 1, Craft 4 en Laravel 11 en ouder zijn end-of-life. Ook CodeIgniter 3 heeft geen officiële ondersteuning voor PHP 8.2 of hoger.
Eén ding wil ik eerlijk zeggen. Een Magento-shop op PHP 5.6 of 7.4 zet je niet in een week over naar PHP 8.4. Daar verhuizen extensies, maatwerk en koppelingen mee, en dat is een migratie, geen update. Wie dat in een paar dagen belooft, belooft wonderen.
Vast op PHP 5.6, 7.x, 8.0 of 8.1? Zo koop je tijd
Kun je niet direct upgraden, dan zijn er manieren om de tijd te overbruggen tot de migratie klaar is. Stand van donderdag 22 oktober, rond 10.45 uur:
- Bouw PHP zelf met de source-backports van het PHP-securityteam voor 7.4, 8.0 en 8.1. Voor 5.6 en 7.0 tot en met 7.3 zijn die er niet.
- Ondřej Surý onderhoudt ook oude PHP-versies voor Debian en Ubuntu, en zegt de fix mee te nemen in alle versies in zijn repository. Op 22 oktober stonden er voor Ubuntu 24.04 (amd64) builds van 21 oktober voor alle versies van 5.6 tot en met 8.1. Controleer met
apt-cache policy php7.4-fpm(pas de versie aan) dat je minstens deze pakketrevisie hebt: 5.6.40-104, 7.0.33-92, 7.1.33-80, 7.2.34-66, 7.3.33-35, 7.4.33-31, 8.0.30-25 of 8.1.34-9. Het pakket noemt de CVE's zelf niet, dus je vertrouwt hier op zijn woord. - Ubuntu Pro dekt PHP 7.2 en 7.4 op Ubuntu 18.04 en 20.04, en Freexian ELTS dekt Debian 10 en 11. Ubuntu Pro bracht de fix uit in USN-8948-2, via de betaalde Legacy-add-on ook voor 16.04 en 14.04. Freexian bracht op 21 oktober updates uit voor php7.0 (Debian 9), php7.3 (Debian 10) en php7.4 (Debian 11).
- HardenedPHP van CloudLinux levert onderhouden builds van oude PHP-versies, van de 5.x-reeks tot en met 8.5, via CloudLinux OS of een TuxCare-licentie, en vaak via je hostingpartij. Op 22 oktober meldde CloudLinux dat gefixte alt-php-pakketten voor alle versies van 5.2 tot en met 8.5 in stable staan, en dat ook de ea-php-pakketten van CloudLinux voor cPanel zijn bijgewerkt.
- TuxCare Extended Lifecycle Support voor PHP dekt PHP 5.2 en hoger op onder meer AlmaLinux, CentOS, Ubuntu en Debian, en belooft kritieke lekken binnen 14 dagen te patchen. Volgens CloudLinux stonden gefixte alt-php-pakketten al eerder in de ELS-repository van TuxCare. Per pakket zie je de status in de CVE-tracker van TuxCare.
- Zend PHP LTS dekt PHP 7.2, 7.3, 7.4 en 8.1. Op 22 oktober vond ik daar nog geen aankondiging.
- Zelf backporten en bouwen, als geen leverancier je versie dekt. Begin bij de backports van het securityteam voor 7.4 tot en met 8.1, of bij distributiepatches die de CVE's noemen, zoals die van Ubuntu, Freexian en AlmaLinux. Met hulp van AI vind je veel sneller de juiste plekken in oude code, maar je verandert hier het geheugenbeheer in de kern van PHP. Een backport die goed lijkt, kan het lek toch openlaten. Laat iemand die de engine kent meekijken, draai de regressietests van de fix en
make test, en test je applicatie voordat de build live gaat. Elke volgende fix voor die build is daarna ook jouw werk.
Zodra een van deze partijen een fix uitbrengt, is dat een reële overbrugging. Het koopt tijd, meer niet. De PHP-versie is dan gepatcht, maar de applicatie zelf blijft oud, met haar eigen bekende lekken.
Als updaten vandaag niet lukt
In de release-aankondigingen is PHP hier duidelijk over: "There are no complete mitigations, updating is the only safe choice." Een PHP-coredeveloper zei het in de nacht voor de release al:
"The only thing I can say is that the only mitigation is patching / upgrading PHP. I sadly know too much."
Gina Peter Banyard, PHP-coredeveloper, op Mastodon, 21 oktober 04.13 uur
Veel maatregelen die woensdagochtend rondgingen, zoals alleen upload progress uitzetten, dekken maar één van de twee lekken. De maatregelen in de volgende twee blokken komen uit het officiële advisory. Ze sluiten specifieke aanvalspaden af, maar maken je installatie niet veilig.
Tegen CVE-2026-109618 (OOM corruption)
- Zet
memory_limit=-1, het liefst op een plek die de applicatie niet kan overschrijven, zoalsphp_admin_valuein de FPM-pool of de Apache-configuratie. Controleer dat geen pool, map of applicatie-instelling er weer een eindige limiet van maakt. Zo kan een aanvaller de geheugenlimiet niet meer gebruiken om PHP te laten falen. Een onderliggende allocatiefout kan het kwetsbare pad nog steeds bereiken. - Zet
post_max_sizelaag: 8M als de applicatie geen uploads nodig heeft, 32M als dat wel zo is. Houdupload_max_filesizeonderpost_max_size. Overweeg ook limieten op de webserver of proxy voor de gedecodeerde requestgrootte, het aantal invoervelden, het aantal multipart-delen, het aantal headers en de nestingdiepte. Die limieten moeten ook gelden voor requests zonder bruikbareContent-Length. Reken niet te hard op deze maatregel: volgens het addendum bovenaan kan een request dat binnen 8M past het geheugen toch laten vollopen. - Begrens beschikbaarheid met een container- of cgroup-limiet, het liefst met een beleid dat alleen de getroffen worker stopt. Gebruik daar geen
RLIMIT_ASofRLIMIT_DATAvoor, want die kunnen juist de kwetsbare allocatiefout veroorzaken. - Gebruikt je site geen multipart-formulieren, de vorm waarin browsers onder meer bestanden uploaden, blokkeer die requests dan op de webserver of proxy, voordat ze PHP bereiken. Heeft een deel van de site wel uploads nodig, beperk de blokkade dan tot de andere paden.
Zo blokkeer je multipart in nginx, in het server-blok van je site:
if ($http_content_type ~* "multipart/form-data") {
return 403;
}
En zo in Apache, in de <Directory> van je site:
<If "%{HTTP:Content-Type} =~ m#multipart/form-data#i">
Require all denied
</If>
Ik heb beide regels getest. Ze zoeken op multipart/form-data zonder puntkomma, en blokkeren dus ook de kommavariant uit het addendum. Er gaan ook Apache-regels rond met %{CONTENT_TYPE}. Die blokkeren niets, want in Apache is dat het type van het antwoord, niet van het request.
Tegen CVE-2026-109619 (stale global state)
- Zet
session.upload_progress.enabled=0en herstart elke worker. Doe dat inphp.ini, een FPM-pool of serverconfiguratie die geldt voordat het request wordt geparst. Vertrouw niet opini_set()of een FPM-.user.ini. Dit blokkeert de bevestigde sessiepaden, maar geen andere varianten. - Zet op PHP 8.5
fatal_error_backtraces=0en herstart elke worker. Dit blokkeert alleen het bevestigde pad via fatal-error-backtraces. - Verwijder ongeldige of deprecated instellingen die per request worden toegepast en al vóór de initialisatie meldingen geven. Die meldingen verbergen met
error_reporting,display_errorsof@helpt niet. - Los fatal errors en execution timeouts op die een aanvaller kan uitlokken, ook in callbacks, upload- of importverwerking en cleanup.
Eigen advies: WAF en offline halen
Dit staat niet in het advisory, maar is wat ik zelf aanraad. Een WAF zoals die van Cloudflare houdt bekende exploits tegen, maar niet elke variant die nog komt. Een manier om bekende WAF-regels te omzeilen is inmiddels gepubliceerd, zie het addendum bovenaan. Cloudflare zegt dat zelf ook:
"Cloudflare has protections in place for known exploit payloads. There will be more variations to come and the only way to fully protect your site is to update php once released."
Dane Knecht, CTO van Cloudflare, op X, 21 oktober 09.06 uur
Haal je een site liever tijdelijk offline, stop dan de webserver of laat die een 503 teruggeven. Zet niet alleen de PHP-handler uit: dan kan je webserver .php-bestanden als platte tekst serveren, inclusief wachtwoorden in je configuratie.
Gepatcht? Kijk dan of er al iemand binnen was
Een update dicht het lek, maar ruimt niet op wat een aanvaller er eerder mee deed. Een webshell, een PHP-bestand waarmee iemand op afstand commando's geeft, blijft gewoon in je webroot staan. Dat geldt ook voor een extra cronjob, een nieuwe SSH-sleutel of een databasewachtwoord dat al is uitgelezen. Yorick R. zette op bufon.nl een uitgebreide checklist online om dat na te lopen. Dit zijn de stappen die ik zelf als eerste zou zetten.
Zoek ruim, vanaf 20 oktober, een dag voor de release. Lees logs het liefst op een centrale plek, zoals een syslogserver of je hostingpanel. Wie een shell op je server heeft, kan de lokale logs aanpassen. Kijk naar:
- POST-requests die op een serverfout eindigden, vooral op pagina's zonder uploads, zoals je homepage of loginpagina. Een aanval laat PHP vaak zonder geheugen raken of crashen.
- PHP-workers die crashten. Gezonde PHP crasht niet, dus elke segfault sinds 20 oktober verdient uitleg.
- PHP-bestanden die sinds 20 oktober zijn veranderd of erbij kwamen, vooral in upload-, cache- en tijdelijke mappen. Kijk ook naar
auto_prepend_filein.user.inien.htaccess. Daarmee laadt een aanvaller code vóór elke pagina, en die blijft werken als je de webshell zelf weghaalt. - Processen van de webgebruiker, zoals
www-data. Die draait PHP, maar start nooit een shell,curl,wgetofnc. - Manieren om terug te komen, zoals cronjobs, systemd-timers, SSH-sleutels, nieuwe gebruikers en sudo-rechten. Kijk in je applicatie ook naar nieuwe beheerders, nieuwe API-tokens en een aangepaste checkout. Op een webshop is een skimmer, code die betaalgegevens afvangt, vaak het echte doel.
Voor Debian en Ubuntu met nginx:
# POST-requests die op een serverfout eindigden
zgrep -hE '"POST [^"]*" 50[0-4] ' /var/log/nginx/access.log*
# Gecrashte PHP-workers
zgrep -hE 'SIGSEGV|signal 11' /var/log/php*-fpm.log*
journalctl -k --since 2026-10-20 | grep -i segfault
# PHP-bestanden die sinds 20 oktober zijn veranderd
find /var/www /tmp /var/tmp /dev/shm -type f \
\( -name '*.php*' -o -name '*.phtml' -o -name '*.phar' -o -name '.htaccess' -o -name '.user.ini' \) \
-newermt 2026-10-20 -ls
grep -rnE 'auto_(prepend|append)_file' /var/www --include=.user.ini --include=.htaccess
# Wat de webgebruiker draait
ps -u www-data -o pid,ppid,lstart,cmd
# Manieren om terug te komen
crontab -l -u www-data
find /etc/cron* /etc/systemd /etc/sudoers.d -newermt 2026-10-20 -ls
find / -name authorized_keys -newermt 2026-10-20 -ls 2>/dev/null
Gebruik je Apache, kijk dan in /var/log/apache2/access.log* en zoek in error.log* naar Segmentation fault. Je eigen deploys en de PHP-update zelf komen ook in deze lijsten terecht. Alles wat je niet zelf hebt veranderd, verdient uitleg. Een aanvaller kan de wijzigingsdatum van een bestand terugzetten, dus vergelijk ook met een bekende goede staat: wp core verify-checksums en wp plugin verify-checksums --all voor WordPress, debsums -c of rpm -Va voor pakketten, git status in de webroot als je met git deployt en docker diff voor containers.
Vind je iets, of kun je het niet uitsluiten, vervang dan vanaf een schone machine de geheimen die PHP kon lezen. Wie code uitvoert als webgebruiker, kan je configuratie lezen. Denk aan databasewachtwoorden uit wp-config.php of .env, API-sleutels van betaal-, mail- en opslagdiensten en de geheime sleutel waarmee je applicatie onder meer cookies ondertekent of versleutelt. In WordPress zijn dat de salts in wp-config.php, in Symfony is dat APP_SECRET en in Laravel APP_KEY. Laravel versleutelt met die sleutel ook data. Zet de oude sleutel daar vanaf Laravel 11 in APP_PREVIOUS_KEYS, anders kun je die data niet meer lezen.
Vind je echt sporen, dan is het geen patchklus meer, maar een incident:
- Haal de server van het netwerk, maar ruim nog niets op. Haal je alleen de webshell weg die je vond, dan waarschuw je de aanvaller en blijven de webshells staan die je niet vond.
- Maak eerst een snapshot van de schijf en kopieer de logs van de server af.
- Bouw een schone server met gepatchte PHP, zet je code opnieuw neer vanuit je repository en zet alleen je data terug. Controleer ook die data, zoals uploads, op PHP-bestanden.
- Kunnen er persoonsgegevens zijn gelekt, dan moet je dat in de regel binnen 72 uur na ontdekking melden bij de Autoriteit Persoonsgegevens.
Vergeet de PHP buiten je websites niet
De websites zelf worden wel gepatcht. Hostingpartijen zijn ermee bezig en containers worden opnieuw gebouwd. Yorick R. voorspelt dat het lastige deel zit in PHP die niemand als PHP-server ziet, en ik denk dat hij gelijk heeft:
- phpMyAdmin dat ooit voor een snelle fix is geïnstalleerd en nooit is weggehaald, vaak op dezelfde server als de database
- apparaten waarvan de webinterface op PHP draait, zoals sommige NAS'en, routers, firewalls, VPN-portalen, printers, camerasystemen en beheerkaarten van UPS'en
- industriële systemen, zoals bedieningspanelen, SCADA-portalen en systemen voor energie- en gebouwbeheer
- de oude urenregistratie, wiki of monitoringtool op een vergeten virtuele machine
Zulke systemen krijgen geen apt upgrade. Ze wachten op firmware van de leverancier, als die nog bestaat, en draaien soms een PHP-versie waarvoor geen fix bestaat. Een webshell op een NAS of op een portaal naast je productiemachines zit bovendien binnen je netwerk. Dat maakt ze vaak een gevaarlijker doelwit dan je website. Kun je ze niet patchen, bepaal dan wie erbij kan:
- Haal ze van internet. Geen port forwards, ook geen tijdelijke.
- Zet ze achter een VPN, alleen voor wie ze nodig heeft.
- Scherm ze af van de rest van het netwerk. Een industrieel portaal hoeft alleen bereikbaar te zijn vanaf de werkplekken die het beheren.
- Vraag je leverancier schriftelijk of het product PHP gebruikt en wanneer er een fix komt.
- Gebruikt niemand ze nog, zet ze dan uit. Die oude phpMyAdmin kan weg.
Hoe ik je kan helpen
Ik ben freelance PHP-developer, met Laravel en Symfony als basis en ervaring met onder meer Magento-modules en het upgraden van oudere PHP-applicaties. Bij dit soort lekken kan ik je op drie manieren helpen.
- Vandaag: in kaart brengen waar je PHP draait en welke versies, patchen binnen je huidige versie, de officiële maatregelen goed doorvoeren en controleren dat ze echt actief zijn.
- Deze week: voor een oude stack de juiste overbrugging kiezen en inrichten, van HardenedPHP, Ubuntu Pro of ELTS tot, waar die je niet dekken, een eigen build waarin ik de fix met hulp van AI backport, toets aan de upstream-patch en test.
- Daarna: een eerlijk upgradeplan naar een ondersteunde PHP- en platformversie, met wat het kost en wat het oplevert. Soms is migreren goedkoper dan blijven lappen.
Wat ik niet beloof: dat je Magento 2.3-shop op PHP 7.4 vrijdag op PHP 8.4 draait. Wat ik wel beloof: een eerlijk antwoord over wat vandaag kan en wat een project wordt. Stuur me welke PHP-versie, welk platform en welke hosting je hebt. Neem contact op.
Over de write-up die woensdagochtend rondging
Voor de release ging PHP-UP-2026 op jackalsyn.com breed rond als uitleg van deze CVE's. Die beschreef een use-after-free in session.upload_progress. De auteur trok de claim later in en hield een bug over die geen code zou uitvoeren en alleen Apache prefork met mod_php zou raken.
Of de write-up precies dezelfde bug beschrijft, is niet bevestigd. Wel staat vast dat de geruststellende conclusie niet opgaat voor wat PHP vandaag dichtte: elke SAPI is geraakt en code-executie is mogelijk. Les voor de volgende keer: behandel een "valt wel mee" van derden tijdens een embargo net zo kritisch als een "het is heel erg", en wacht op het officiële advisory.
Written by AI, directed by Human
AI hielp mee met schrijven. De keuzes en de ervaring erachter zijn van mij.
Bronnen
PHP en de PHP Foundation
- php.net: Security advisory, critical remote code execution vulnerabilities
- GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
- GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
- PHP Foundation: Today's PHP security release and how we're strengthening PHP security
- PHP: supported versions
- php.net: downloads, checksums en handtekeningen
- php/web-php: commits van de php.net-website
- PIE: PHP Installer for Extensions, opvolger van PECL
Nieuws en instanties
- AD: liveblog beveiligingslek PHP
- AD: Ziekenhuizen, MijnOverheid en RTL: deze sites zijn offline door beveiligingslek bij PHP
- NOS: liveblog PHP-lek, MijnOverheid en DigiD weer online
- NU.nl: liveblog PHP, belangrijke veiligheidsupdate is live
- Reformatorisch Dagblad (ANP): Allerlei websites offline om waarschuwing PHP
- Tweakers: PHP waarschuwt voor twee ernstige bugs die makkelijk uit te buiten lijken
- Tweakers: Securityexperts vinden derde bug in PHP en claimen dat patch incompleet is
- NCSC (websitebericht): Ernstige kwetsbaarheden in PHP: bereid je voor op patchen
- CISA: Known Exploited Vulnerabilities Catalog
- Autoriteit Persoonsgegevens: meldplicht datalekken
Ontwikkelaars en onderzoekers
- Gina Peter Banyard (PHP-coredeveloper) op Mastodon, 21 oktober 04.13 uur
- Dane Knecht (CTO Cloudflare) op X, 21 oktober 09.43 uur
- Dane Knecht (CTO Cloudflare) op X, 21 oktober 09.06 uur
- Nicolas Krassas op X, 21 oktober 19.40 uur
- Nicolas Krassas: php2shell-lab op GitHub
- Elise Amber Katze op Mastodon, 21 oktober 16.32 uur
- oss-security: Re: CVE-2026-109619 (Aaron Rainbolt, 21 oktober)
- Mattias Geniar: early mitigation steps
- Mattias Geniar: how to apply the patches
- Bufon (Yorick R.): PHP2Shell, patching is phase 1. Phase 2 and 3 are coming
- PHP-UP-2026 (gecorrigeerde write-up)
Distributies, pakketbronnen en images
- Ubuntu: CVE-2026-109618
- Ubuntu: USN-8948-1, PHP vulnerabilities
- Ubuntu: USN-8948-2, PHP-updates voor Ubuntu Pro (14.04 tot en met 20.04)
- Ubuntu: release cycle
- Debian security tracker: CVE-2026-109618
- Debian security tracker: php8.4
- Debian LTS
- Red Hat: CVE-2026-109618
- AlmaLinux: php2shell, gepatchte PHP-pakketten uitgebracht
- AlmaLinux ELevate
- Remi's RPM repository: configuratiewizard
- packages.sury.org: README voor het toevoegen van de PHP-bron
- deb.sury.org: issue 145 over CVE-2026-109618/109619
- Docker Hub: officiële php-images
- Alpine Linux: php84-pakketten
- FrankenPHP: releases
- FrankenPHP 1.13.2
- Plesk Obsidian: changelog
Langere ondersteuning voor oude PHP-versies
Platforms en frameworks
- WordPress: PHP compatibility and WordPress versions
- WooCommerce: PHP updaten
- Adobe Commerce: system requirements
- Adobe Commerce: versies en supportperiodes
- OpenMage: requirements
- Shopware 6.6: requirements
- PrestaShop 9: system requirements
- Drupal: PHP requirements
- Joomla: technical requirements
- TYPO3: versies en support
- Craft CMS: supported versions
- Nextcloud: maintenance and release schedule
- Laravel: release notes en supportbeleid
- Symfony: releases
- CodeIgniter 4: server requirements
- CodeIgniter 3: server requirements
- CakePHP: versies en support
- Yii: release cycle
- Zend Framework 1: end of life