Woensdagochtend 21 oktober 2026 werd bekend dat er een ernstig lek in PHP zat, de taal waar WordPress, Laravel en het grootste deel van het web op draait. De naam: php2shell. De patch zou om vier uur ’s middags komen. Tot die tijd had iedereen met een PHP-site dezelfde vraag: wat doe ik de komende uren?
Veel organisaties kozen hetzelfde antwoord: uit. RIVM, de Tweede Kamer, VVD, SGP, ziekenhuizen, kinderopvangorganisaties, de CPNB, Stedin. Ik heb die middag gekeken wat een bezoeker dan te zien kreeg. Dat verschilde nogal.
Wat ik zag om kwart over drie
Ik nam de ruim honderd sites die nu.nl in zijn liveblog noemde en vroeg bij elk de voorpagina op, zoals een bezoeker dat doet. Dit was de stand om 15:15, drie kwartier voor de patch:
| Wat de bezoeker zag | Aantal sites |
|---|---|
| Een nette onderhoudspagina met uitleg | ruim veertig |
| Een kale foutmelding van de server of de proxy | een tiental |
| Niets: verbinding geweigerd of een time-out | zestien |
| De site werkte gewoon | dertig |
| Niet te beoordelen (bot-check of privacymuur) | negen |
De 104 sites uit het liveblog van nu.nl, voorpagina opgevraagd op 21 oktober 2026 om 15:15.
Een nette onderhoudspagina met uitleg
- Aantal sites
- ruim veertig
Een kale foutmelding van de server of de proxy
- Aantal sites
- een tiental
Niets: verbinding geweigerd of een time-out
- Aantal sites
- zestien
De site werkte gewoon
- Aantal sites
- dertig
Niet te beoordelen (bot-check of privacymuur)
- Aantal sites
- negen
De eerste groep deed het goed. ANWB, Thuisarts, D66, KNVB, de gemeente Breda, MijnOverheid en het NCSC toonden een pagina in eigen huisstijl: we zijn er even niet, dit is waarom, zo bereik je ons. De helft noemde de PHP-update bij naam.

Eén ding ging bij die eerste groep vaak mis, en je ziet het niet op het scherm. Ruim twintig van die nette pagina’s kwamen met statuscode 200, de code voor “alles in orde”. Een onderhoudspagina hoort een 503 te geven, “tijdelijk niet beschikbaar”. Met een 200 ziet Google een gewone pagina met als enige inhoud “we zijn er even niet”, en kan die de index in gaan als de nieuwe versie van je site. Je bewakingsdienst ziet ook niets, want 200 is groen. Met een 503 komt Google later terug en slaat de bewaking wel alarm. Het is één regel in de webserver, en gisteren stond hij bij de helft verkeerd.
De tweede groep had ook de stekker eruit, maar zonder bordje. Stedin gaf een 502 van de Azure-gateway, Veiligheidsregio Haaglanden een 502 van nginx, JA21 een foutpagina van Cloudflare. Bij ETZ, FC Twente en het HMC kwam een lege 503 zonder titel.

De derde groep was er helemaal niet. Bij RIVM, de Tweede Kamer, SGP, het St. Antonius, het Albert Schweitzer, Maastricht UMC+, BovenIJ en de CPNB weigerde de server de verbinding, of bleef de browser wachten tot hij het opgaf. De bezoeker ziet dan de eigen foutpagina van Chrome, “Deze site is niet bereikbaar”, zonder huisstijl, uitleg of telefoonnummer. Bij VVD deed Cloudflare het woord: “Connection timed out”, met een rood kruis bij de host.

Waarom ik me daarover verbaasde
Het offline gaan zelf vond ik verstandig. Een lek dat zonder inloggen misbruikt kan worden, met een patch die pas over een paar uur komt: dan wil je niet dat PHP verzoeken van buiten verwerkt. Ik heb het voor negen sites zelf ook gedaan.
Waar ik me over verbaasde is hoe. De verbinding weigeren is één manier om PHP niets te laten verwerken. Een andere is PHP uitzetten en een statische pagina laten staan, met werkende https. Voor de aanvaller is dat even dicht: een server die PHP niet uitvoert, kan geen PHP-lek hebben. Voor de bezoeker is het verschil groot. De ene ziet een pagina van het ziekenhuis die zegt dat er onderhoud is en welk nummer je belt. De andere ziet een foutpagina van Chrome en denkt dat het ziekenhuis weg is, of gehackt.
Organisaties met tientallen mensen in de IT en budgetten waar ik niet aan kan tippen kozen voor de kale variant. Geld is het denk ik niet. Zo’n pagina moet er al liggen voordat je hem nodig hebt. Op de dag zelf is er geen tijd om hem te maken, en dan is de firewall de snelste knop.
Bij een groot landschap met honderden applicaties is die knop soms ook de enige die snel genoeg is. En ziekenhuizen en overheden hadden die dag meer te regelen dan hun voorpagina: DigiD lag eruit, apps en koppelingen ook. Dat de voorpagina dan kaal is, zegt vooral dat hij onderaan de lijst stond.
Aan de andere kant van het spectrum zaten de grote hostingpartijen met gedeelde servers. Namen doen er niet toe. Die hebben in de loop van de ochtend alle websites op hun gedeelde servers offline gehaald, zonder overleg, en de mail daarover kwam daarna. Vanmiddag waren ze nog bezig om alles weer online te zetten. Overleg was voor hen ook niet mogelijk, met tienduizenden klanten op één soort server kan de procedure haast niet anders. De communicatie kon beter. Maar wie een paar euro per maand betaalt, koopt precies dit: op zo’n dag bepaalt de hoster, en jij hoort het achteraf.
Mijn woensdag
Ik beheer 28 servers met WordPress- en Laravel-sites van klanten. Zo ging de dag:
- ’s Ochtends vroeg de techniek. De onderzoekers noemden één PHP-instelling als ingang, de voortgangsmelding bij uploads. Die zette ik op alle servers uit. Daarnaast blokkeerde ik op de webserver alle uploads naar PHP, zodat ook de tweede ingang dicht zat. Formulieren met bijlagen werkten die middag niet, de rest van elke site wel. En een bewaker erbij: een klein script dat elke vijf minuten kijkt of PHP iets doet wat het niet hoort te doen, zoals een shell starten, en dat dan in Slack meldt.
- Direct daarna de klanten. Iedereen kreeg een mail met wat er aan de hand was, wat ik al had gedaan en wat de keuzes en de gevolgen waren. Klanten met een kritieke site of een Premium- of Premium+-pakket belde ik ook, om samen te kiezen: de site dicht, of open laten met bewaking en zoveel mogelijk belemmering, en alleen dicht als het echt moest.
- Twee sites gingen wel direct dicht. Daar zag ik verdachte dingen in de logs. Ik haalde ze meteen offline, nam direct maatregelen en liet een scan draaien, en de klant kreeg bericht dat de site dicht stond en waarom.
- Negen sites in de onderhoudsstand. Een eigen pagina in de huisstijl van de klant, met een 503-code, een telefoonnummer en het certificaat gewoon werkend. PHP stond daar uit.
- Kwart voor vier kwam de patch, iets eerder dan aangekondigd. Om half vijf stonden alle 28 servers op de gefixte versie, waren de blokkades weg en de negen onderhoudspagina’s vervangen door de echte site. Daarna een scan op elke server of er in de tussentijd iets was binnengekomen. Niets gevonden. De bewaker laat ik nog een week draaien.
- ’s Avonds een afrondmail aan alle klanten: wat er is gedaan, wat de stand is, en dat de bewaking aan blijft. Op zo’n dag is communicatie de helft van het werk. Wie niets hoort, gaat zelf invullen wat er aan de hand is.

Wat ik ervan onthoud: het liep. De voorzorgen die ik de afgelopen jaren heb ingebouwd bleken precies voor zo’n dag te zijn. Ik kon van server naar server schakelen zonder na te denken over hoe het daar ook alweer zat, en heb nauwelijks stress gehad. De reacties van klanten op de mails en de telefoontjes waren hartelijk, en dat deed me goed. Ze wisten de hele dag waar ze aan toe waren.
Een dag later
Vanmiddag om 15:15 heb ik dezelfde ruim honderd sites nog eens opgevraagd. Drieënnegentig werkten gewoon. Acht zitten achter een bot-check en zijn voor een script niet te beoordelen; gisteren ook al. Eén site stond nog op de onderhoudsmelding van gisteren: onsoranje.nl, terwijl knvb.nl en voetbal.nl van dezelfde organisatie wel terug waren.
Alle zestien sites die gisteren de verbinding weigerden, waren binnen een dag terug. De tien met een kale foutmelding ook. Het verschil zat dus niet in hersteltijd of in veiligheid, alleen in wat de bezoeker die middag te zien kreeg.
Wat je klaar wilt hebben voor de volgende keer
Dit gebeurt nog een keer, al weet niemand wanneer. Vijf dingen die er dan al moeten liggen:
- Een onderhoudspagina in je eigen huisstijl, als los HTML-bestand op de server. Met wat er aan de hand is, hoe lang het ongeveer duurt en hoe je de organisatie bereikt. Geen PHP erin.
- Een manier om die pagina aan te zetten zonder PHP te raken, en met een 503. Op nginx is dat een regel die alles naar dat bestand stuurt met die code. Test hem één keer, als er niets aan de hand is, en kijk dan ook wat de statuscode is. Gisteren stond die bij de helft op 200, en dat kost je zoekresultaten.
- Een certificaat dat blijft werken als de site dicht is. Een onderhoudspagina op http, of met een certificaatfout, leest als een hack.
- Weten waar je PHP vandaan komt. Van de distributie, van een extra pakketbron, van een beheerpaneel, van je cloudleverancier? Gisteren kwamen de patches op verschillende momenten uit verschillende bronnen. AWS had voor zijn eigen PHP-versie pas vannacht rond twee uur een update klaarstaan, tien uur na PHP zelf. Wie niet wist waar zijn PHP vandaan kwam, zat te wachten op iets dat al klaarstond, of dacht dat hij klaar was terwijl de update nog moest komen.
- Weten wie je belt. Je hoster, je beheerder, of jezelf. En of die persoon op een woensdagmiddag opneemt.
Nalezen: het liveblog van nu.nl van 21 oktober 2026 met de lijst van getroffen organisaties.
Wil je weten hoe jouw site er op zo’n dag voor zou staan? Bel, dan loop ik de vijf punten met je door. Bij een onderhoudsabonnement zijn ze geregeld.