Op 21 oktober 2026 bracht het PHP-project fixes uit voor twee kritieke kwetsbaarheden in PHP zelf, CVE-2026-109618 en CVE-2026-109619, samen PHP2Shell genoemd. Met één ongeauthenticeerd verzoek kan een aanvaller code uitvoeren op de webserver of werkgeheugen uitlezen waarin wachtwoorden, tokens en API-sleutels staan. De details lekten een dag te vroeg uit, en de honeypots van Amazon registreerden al op 17 oktober een aanvalspoging, vier dagen voordat de patch bestond.
Dit artikel is voor wie er binnen een Nederlandse of Vlaamse organisatie van 250 tot 5.000 medewerkers verantwoordelijk voor is: de IT-manager, informatiemanager of security officer. Crux Digits host, patcht en beheert geen servers; dat doet uw ICT-partner of uw eigen IT-afdeling. Wat wij toevoegen is het deel van PHP2Shell waar een patch niet bij kan: applicaties waarvan de code te oud is om te draaien op een PHP-versie die nog fixes krijgt.
Wat PHP2Shell is
Beide kwetsbaarheden zitten in de PHP-engine, onder de applicatie. Het maakt dus niet uit of de site op WordPress, Drupal, Magento, Laravel of eigen code draait. De eerste beschadigt verzoekgegevens wanneer PHP halverwege het opzetten van een verzoek zonder geheugen komt te zitten; de tweede laat verzoekstatus achter nadat het geheugen is vrijgegeven, waarna het volgende verzoek op dezelfde worker die status gebruikt. Beide scoren 9,2 op CVSS v4.0. De PHP-beveiligingsrelease noemt elke installatie die webverzoeken afhandelt kwetsbaar: PHP-FPM, Apache met mod_php, php-cgi, FrankenPHP en LiteSpeed. Het risico is het hoogst bij mod_php, waar PHP een werkende exploit heeft die afgaat voordat er ook maar één regel applicatiecode draait.
De herstelde versies zijn PHP 8.5.12, 8.4.27, 8.3.36 en 8.2.35. PHP 8.1 en ouder krijgen geen release. Het project publiceerde minimale bron-backports voor 7.4, 8.0 en 8.1 en verwijst verder naar uw distributie of leverancier, of naar een upgrade naar een ondersteunde versie. De ontdekker, Wiz, schrijft dat één onderzoeker met AI-modellen de bugs in ongeveer een week vond en tot exploit uitwerkte. Dat is hun eigen verslag, maar het past in de richting die we zien: fouten in oude, breed gebruikte code worden sneller gevonden, door aanvallers en verdedigers allebei.
"PHP patchen" is drie klussen met drie eigenaren
Elk advies eindigt met dezelfde opdracht: updaten. In een omgeving met een paar honderd applicaties valt die opdracht uiteen in drie klussen bij drie verschillende partijen, en alleen de eerste is snel klaar.
De eerste klus is de runtime op PHP 8.2 of nieuwer die uw ICT-partner of cloudplatform draait. Dat is een pakketupdate, gevolgd door een stap die makkelijk wordt vergeten: het NCSC-NL wijst erop dat workers die al draaiden de kwetsbare code blijven uitvoeren tot ze opnieuw worden gestart. Bij containers speelt hetzelfde een laag hoger. Google zegt het onomwonden: zelfgebouwde images zijn de verantwoordelijkheid van de klant en moeten op een gepatcht basisimage opnieuw worden gebouwd en uitgerold, niet alleen gescand.
De tweede klus is PHP die meekwam in iets wat u heeft gekocht: een appliance, een hostingpaneel zoals cPanel of Plesk, een Windows-product met een eigen php-cgi.exe. Huntress noemt precies deze installaties als de installaties die over het hoofd worden gezien. Hier patcht de leverancier en volgt u de leverancier. Het NCSC-NL houdt in dezelfde repository een lijst bij van softwareproducten met een PHP-afhankelijkheid; leg uw contractenlijst er deze week naast.
De derde klus zijn uw eigen PHP-applicaties op 8.1 of ouder: het leveranciersportaal uit 2017, de intranetmodule die niemand meer aanraakte sinds de ontwikkelaar vertrok, de Laravel- of Symfony-applicatie die vastzit op PHP 7.4 omdat de gebruikte frameworkversie PHP 8 nooit heeft ondersteund. Hiervoor bestaat geen upstream-fix. Uw ICT-partner kan de runtime niet zomaar ophogen, want de applicatie werkt dan niet meer op PHP 8.2, en uw code is niet van hem en wordt niet door hem aangepast. Hier verandert PHP2Shell van een patch in een project, en hier ligt het meestal zonder eigenaar.
Waarom het versienummer in uw inventaris kan misleiden

De meeste inventarissen leggen het upstream-versienummer vast, en bij dit advies kan dat nummer in beide richtingen verkeerd zijn. Distributies verwerken beveiligingsfixes in de versie die ze leverden, zodat een gepatcht pakket nog steeds een ouder upstream-nummer kan tonen. Qualys zegt dat voor PHP2Shell met zoveel woorden: volg het advies van de leverancier, want een backport kan het oude versienummer houden. Een scanner die alleen het nummer leest, markeert een gepatchte distributiebuild als kwetsbaar en laat, erger nog, een ongepatchte zelfgecompileerde 8.3 door als niemand het patchniveau controleert.
Vraag daarom per PHP-installatie vier velden in plaats van één: de upstream-versie, de pakketrelease of bouwbron, de SAPI (FPM, mod_php, CGI, FrankenPHP of LiteSpeed) en of de installatie vanaf internet bereikbaar is. Met die vier deelt u de omgeving in één middag op in de drie klussen hierboven, en ziet u welke internetgerichte mod_php-hosts als eerste aan de beurt zijn.
Wat er breekt als oude PHP-code naar 8.2 gaat
Een upgrade vanaf 7.4 of 8.1 is zelden een herschrijving, maar ook nooit alleen een nieuw versienummer. PHP 8.0 schrapte functies waar oudere code op leunt, zoals each() en create_function(), en veranderde hoe strings met getallen worden vergeleken: 0 == "abc" geeft nu false waar het vroeger true gaf. PHP 8.1 markeerde het doorgeven van null aan ingebouwde functies die een string verwachten als verouderd, wat in losjes geschreven code een stroom waarschuwingen oplevert. PHP 8.2 deed hetzelfde met dynamische properties, die veel oudere codebases overal aanmaken. Bovenop de taal zit het framework: een frameworkrelease van vóór PHP 8 sluit PHP 8 doorgaans uit in zijn composer.json, dus het framework moet mee, met zijn eigen brekende wijzigingen.
Het meeste hiervan is mechanisch werk, en daar bestaat goed gereedschap voor. Rector past refactorregels per PHP-versie toe, PHPCompatibility markeert code die op een doelversie niet draait, en statische analyse met PHPStan vindt de typefouten die de nieuwe versies blootleggen. Wat de doorlooptijd en het risico bepaalt, is of er tests zijn. Een applicatie met een testsuite kan stap voor stap worden geüpgraded, met elke wijziging bewezen; een applicatie zonder tests krijgt eerst karakteriseringstests, geschreven tegen het huidige gedrag, zodat de upgrade kan aantonen dat er niets veranderde.
Een plan voor deze week, per eigenaar
Vraag vandaag uw ICT-partner om de lijst met de vier velden hierboven, en laat bevestigen dat na de update elke worker opnieuw is gestart en elk containerimage opnieuw is gebouwd. Vraag elke leverancier van de NCSC-NL-lijst die u gebruikt om zijn advies en datum. Dat zijn vragen, geen taken voor u zelf, en ze maken de eerste twee klussen zichtbaar.
Neem voor elke internetgerichte installatie op PHP 8.1 of ouder nu de tijdelijke maatregelen van PHP: zet session.upload_progress.enabled op 0 in php.ini of de FPM-pool en start elke worker opnieuw, houd post_max_size laag en dwing limieten op de verzoekgrootte af in de webserver of proxy. PHP zegt uitdrukkelijk dat deze maatregelen een installatie niet veilig maken; ze kopen tijd. Zet de applicatie waar het kan achter een VPN of beperk haar tot bekende adressen tot de code is overgezet.
Controleer de logs tot minstens half oktober terug, want de eerste geregistreerde poging was er al vóór het lek. Huntress adviseert te zoeken naar PHP-workerprocessen (php-fpm, httpd, apache2, php-cgi) die shells of downloadtools starten, en naar verkenningscommando's zoals whoami of uname vanaf een webserver. Wiz voegt daar herhaalde HTTP 500-antwoorden na multipart-verzoeken, geheugenlimietfouten en ongewoon grote PHPSESSID-cookies aan toe. Valt u onder de Cyberbeveiligingswet, dan kan een bevestigde compromittering een significant incident zijn met een vroegtijdige waarschuwing binnen 24 uur; ons artikel over de ketenzorgplicht beschrijft wie in de keten die plicht draagt.
Besluit binnen een maand per applicatie op PHP 8.1 of ouder: upgraden, vervangen of uitfaseren. Leg het besluit vast met een datum en een eigenaar. Een applicatie die niet binnen één sprint naar een ondersteunde runtime kan, is een blijvende blootstelling, en de vraag wie het versienummer van een component beheert is dezelfde die we twee dagen geleden voor AI-gateways stelden.
Waar Crux Digits in beeld komt
Wij nemen de derde klus en laten de eerste twee waar ze horen. Uw ICT-partner blijft de servers draaien, de pakketten installeren en de workers herstarten. Wij werken aan de applicatie: een code-audit die laat zien wat er op PHP 8.2 of 8.4 breekt, hoeveel daarvan het gereedschap oplost, welke testdekking er is en wat de frameworkupgrade inhoudt, gevolgd door een upgrade met een vaste scope. AI-modellen doen het grootste deel van het mechanische refactorwerk en schrijven de ontbrekende karakteriseringstests voor; een engineer beoordeelt elke wijziging voordat die wordt samengevoegd, en er gaat niets live wat de tests niet hebben bewezen.
Uw ICT-partner krijgt aan het eind een uitrolbare applicatie op een ondersteunde PHP-versie, de testsuite die het gedrag bewijst en een kort draaiboek voor de volgende upgrade. De code blijft van u. Blijkt vervangen voordeliger dan upgraden, dan staat dat in de audit; dat is een besluit voor u, geen verkoop voor ons.
Wilt u de derde klus laten bekijken, dan legt onze pagina over maatwerksoftware uit hoe we met vaste stappen werken.
Laatst bijgewerkt: 22 oktober 2026.
Software rond uw proces en uw data, met AI waar het de uitkomst verandert. Elke week iets dat werkt, en de code is van u.
Maatwerksoftware in Nederland →


