PHP2Shell, deze week
Op 21 oktober 2026 bracht het PHP-project vier releases tegelijk uit, 8.5.12, 8.4.27, 8.3.36 en 8.2.35, om twee kritieke fouten in de interpreter zelf te dichten1. Niet in WordPress. Niet in een plugin. In PHP.
Beide krijgen 9,2 op CVSS 4.0. Beide maken remote code execution mogelijk zonder login. De onderzoekers die ze vonden zeggen het bereik zonder omwegen: “Every PHP version released in the last decade is affected by at least one of these vulnerabilities, going back to version 5.4.”2
De eigen advisory van het PHP-project zegt de rest:
| Wat de advisory zegt | Wat het voor jou betekent |
|---|---|
| “unauthenticated remote code execution” | niemand heeft een account op je site nodig |
| “risk highest for mod_php” | de meest gangbare ouderwetse Apache-opstelling staat er het slechtst voor |
| “before any application code runs” | je eigen code, hoe zorgvuldig ook, heeft niets in te brengen |
| “There are no complete mitigations, updating is the only safe choice.” | geen configuratiewijziging redt je |
| “PHP 8.1 and older no longer receive updates” | een groot deel van het web krijgt helemaal geen fix |
En het werd al gebruikt voordat iemand het te horen kreeg. Het honeypotnetwerk van Amazon registreerde een poging op 17 oktober, vier dagen voor de bekendmaking3. watchTowr zag het op de 21e in het wild, en werkende proofs of concept waren binnen enkele uren na de patch openbaar4.
Beide bugs zijn geheugenveiligheidsbugs. De ene zit in hoe de interpreter opruimt nadat het geheugen op is. De andere is een use-after-free: geheugen van het ene request wordt vrijgegeven en daarna opnieuw gelezen, en het volgende request op dezelfde worker kan het zien56. Onthoud die tweede. Hij komt later terug.
Niets hiervan is nieuw. Daar gaat deze post over. PHP2Shell is geen ongeluk dat een zorgvuldige taal overkwam. Het is de nieuwste bladzijde in een dossier van bijna dertig jaar, en elk getal erin is openbaar.
Eén proces houdt alles vast
Van november 2014 tot april 2017 was ik third-line Linux-engineer op het cloud- en hostingplatform van Pulsant. Een deel van dat werk was het inrichten van PHP-FPM-omgevingen voor e-commerceklanten en die afstellen op snelheid.
Inbraken via PHP waren gewoon. Niet af en toe. Gewoon. En ze kwamen neer op twee oorzaken: slechte inrichting, en geen scheiding tussen de front end en de back end.
De taal maakt die tweede de standaard. Een typische PHP-site is één proces. De paginatemplate, de bedrijfslogica en de SQL zitten allemaal in dezelfde request handler, vaak in hetzelfde bestand. Dat proces draait als één gebruiker van het besturingssysteem. Het kan het databasewachtwoord lezen, want dat wachtwoord staat in een bestand naast de code. En het kan meestal naar zijn eigen webroot schrijven, want zo werken uploads en updates.
Dat is niet mijn mening over hoe PHP wordt ingericht. Het is wat PHP en WordPress zelf documenteren.
| Bron | Wat er staat |
|---|---|
| PHP-handleiding, Apache-module | als PHP als Apache-module draait, “it inherits Apache’s user permissions”, en “a malicious script could access and modify the database, even without a username and password”7 |
| PHP-handleiding, Apache-installatie | “The mod_php approach embeds PHP directly into every Apache httpd worker process.”8 |
| WordPress, wp-config | het bestand “is located in the root of your WordPress file directory and contains … database connection information”9 |
| WordPress, bestandsrechten | wp-config.php “is initially created with 644 permissions, and it’s a hazard to leave it like that”10 |
| WordPress, hardening | de databasegebruiker “only needs” SELECT, INSERT, UPDATE en DELETE, en dan “it is NOT recommended to revoke these privileges”11 |
Lees die laatste rij nog eens. De leverancier vertelt je hoe least privilege eruit zou zien, en vertelt je daarna het niet te doen, omdat updates het schema veranderen.
Vergelijk de gesplitste versie. De front end rendert pagina’s en heeft geen geheimen. De back end is een aparte service met een eigen gebruiker, een smalle API en geen schrijfrechten op zijn eigen code. Het database-account kan wat de back end nodig heeft en verder niets. De richtlijn van OWASP zegt hetzelfde in eigen woorden: “The application’s backend database should be isolated from other servers”, op “a dedicated internal network segment”12. De eigen handleiding van PHP zegt dat applicaties “should never connect to the database as its owner or a superuser”13.
Niets daarvan is exotisch. Zo ziet een fatsoenlijk proces eruit. Waarom het hier telt is eenvoudig. In het gesplitste model levert een bug in de front end een aanvaller een front end op. In het gebruikelijke PHP-model levert een bug waar dan ook de templates, de code, de credentials en de data op, in één keer.
PHP-FPM helpt, en de installatiegids van PHP noemt het nu de aanbevolen manier om PHP onder Apache te draaien8. De pools kunnen workers starten “with different uid/gid/chroot/environment”14. Maar een pool per site is nog steeds één site per proces, met alles wat die site heeft. Het is een betere muur tussen klanten. Het is geen muur binnen de applicatie.
Houd dat beeld vast bij elke sectie hieronder. Elke bug in het dossier komt op dat proces terecht.
Negenentwintig jaar CVE’s
De National Vulnerability Database zet elke CVE tegen de PHP-interpreter onder één productidentificatie, cpe:2.3:a:php:php. Vraag het, en het antwoord is 75715.
Dat aantal is alleen de interpreter. Geen WordPress, geen Drupal, geen plugins, geen frameworks. Alleen het programma dat je PHP draait.
| Periode | CVE’s | Geheugencorruptie | Wat er speelde |
|---|---|---|---|
| 1997 tot 2006 | 93 | 3 | vroeg web, weinig classificatie |
| 2007 | 114 | 19 | de Month of PHP Bugs |
| 2008 tot 2014 | 187 | 54 | gestage achtergrond |
| 2015 tot 2017 | 208 | 122 | de jaren van unserialize en geheugen |
| 2018 tot 2023 | 100 | 63 | minder, nog steeds vooral geheugen |
| 2024 tot 2026 | 55 | 27 | PHP2Shell valt in dit venster |
| Totaal | 757 | 288 |
Twee pieken springen eruit. De eerste is maart 2007, toen een voormalig lid van het PHP-securityteam de Month of PHP Bugs hield en fouten in de Zend Engine, de PHP-kern en de extensies “on a day by day basis” openbaar maakte16. Hij had het PHP Security Response Team opgericht, was eruit gestapt, en zei waarom: “I dislike the ways bugs are handled”17. Als de oprichter van het securityteam van een project vertrekt en elke dag een bug publiceert, weet je hoe het er van binnen aan toe ging.
De tweede piek is 2016: 120 CVE’s, 65 daarvan geheugencorruptie. Daarover hieronder meer.
Het geheugencijfer is een ondergrens, geen schatting. NVD geeft een flink aantal oudere bugs het label “Other” in plaats van een type zwakte, waaronder een paar van de use-after-frees in de volgende sectie. Het echte cijfer ligt hoger. Ik gebruik het cijfer dat ik kan laten zien.
De engine is in C geschreven
Hier moet het argument over geheugenveiligheid zorgvuldig worden gemaakt, want een PHP-ontwikkelaar wijst er terecht op dat zijn code nooit malloc aanroept. PHP-scripts beheren geen geheugen met de hand. Je kunt in PHP geen buffer overflow schrijven zoals in C.
Dat hoeft ook niet. De interpreter die je script draait is in C geschreven, en de extensies ook. Elke byte onvertrouwde invoer die je site ontvangt, elke header, elke upload, elk formulierveld, elke cookie, wordt door die C geparsed voordat jouw code hem ziet. Als die C fout is, maakt je zorgvuldige PHP niet uit. PHP2Shell bewees het: de advisory zegt dat de aanval kan afgaan “before any application code runs”1.
Het dossier laat zien wat die C fout heeft gedaan:
| CWE-klasse | Wat het is | CVE’s in de PHP-interpreter |
|---|---|---|
| CWE-119 | fouten in geheugenbuffers, algemeen | 93 |
| CWE-125 | lezen buiten de grenzen | 50 |
| CWE-190 | integer overflow | 35 |
| CWE-189 | numerieke fouten, ouder label | 33 |
| CWE-416 | use after free | 27 |
| CWE-787 | schrijven buiten de grenzen | 26 |
| CWE-476 | null pointer dereference | 20 |
Dat zijn de klassen die de veiligheidsdiensten bedoelen als ze het over geheugenveiligheid hebben. In november 2022 adviseerde de NSA organisaties “to consider making a strategic shift from programming languages that provide little or no inherent memory protection, such as C/C++, to a memory safe language when possible”18. In december 2023 plakte CISA er een getal op, met het Britse National Cyber Security Centre onder de medeauteurs: “two-thirds of reported vulnerabilities in memory unsafe programming languages still relate to memory issues”19.
Geen van beide documenten noemt PHP. Dat hoeft ook niet. Ze noemen de taal waarvan PHP gebouwd is.
Het ergste herhaalde voorbeeld is unserialize(), de functie die een opgeslagen string weer in PHP-objecten omzet. Die heeft dezelfde klasse bug, op dezelfde plek, meer dan eens gehad:
| CVE | Waar | Wat NVD vastlegt |
|---|---|---|
| CVE-2014-8142 | process_nested_data | use-after-free in unserialize20 |
| CVE-2015-0231 | dezelfde functie | “exists because of an incomplete fix for CVE-2014-8142”21 |
| CVE-2015-2787 | afhandeling van __wakeup | use-after-free in unserialize |
| CVE-2016-5771 | SPL, met garbage collection | use-after-free in unserialize22 |
| CVE-2016-5773 | ZipArchive, met garbage collection | use-after-free in unserialize |
De PHP-handleiding weet het. De pagina van de functie draagt de waarschuwing: “Do not pass untrusted user input to unserialize() regardless of the options value of allowed_classes.”23 Dat is een taal die je vertelt dat een van zijn eigen ingebouwde functies niet veilig is voor precies datgene waar de meeste webcode de hele dag mee werkt.
Dan is er PHP-FPM, de procesmanager die de installatiegids van PHP zelf aanraadt boven mod_php. In oktober 2019 liet CVE-2019-11043 zien dat “in certain configurations of FPM setup it is possible to cause FPM module to write past allocated buffers … opening the possibility of remote code execution”24. De configuratie in kwestie was een gangbare nginx-opstelling. Het werd op 24 oktober 2019 opgelost25. CISA zette het later in zijn catalogus van kwetsbaarheden waarvan misbruik bekend is, gemarkeerd als gebruikt in ransomwarecampagnes26.
De PHP Foundation heeft wel een echte securityaudit van de broncode van de interpreter laten doen, en dat verdient lof. De resultaten, gepubliceerd op 10 april 2025, vonden 27 problemen, 17 daarvan met gevolgen voor de veiligheid27. Dat is goede praktijk en het zou normaal moeten zijn. Het zijn ook 17 extra, in een audit van een codebase die al bijna drie decennia aan openbare bugrapporten achter de rug had.
De taal maakte dezelfde fouten een verdieping hoger
De C is één laag. De taal erbovenop maakte in zijn ontwerp dezelfde soort fout: invoer vertrouwen die het niet had mogen vertrouwen, en er jaren over doen om daarmee te stoppen.
| Feature | Wat het deed | Standaard uit of deprecated | Verwijderd | Duur |
|---|---|---|---|---|
register_globals | maakte van requestparameters scriptvariabelen | uit in 4.2.0, 22 april 200228 | 5.4.0, 1 maart 201229 | tien jaar |
| magic quotes | escapete invoer automatisch, en verkeerd | deprecated 5.3.0, 30 juni 2009 | 5.4.0, 1 maart 201230 | drie jaar |
preg_replace /e | evalueerde de vervanging als PHP-code | deprecated 5.5.0, 20 juni 201331 | 7.0.0, 3 december 201532 | tweeënhalf jaar |
allow_url_include | liet include code over het netwerk ophalen | deprecated 7.4.033 | ||
| phar-metadata | automatisch geünserialiseerd bij bestandstoegang | opgelost in 8.034 | ||
0 == "foobar" | vergeleek als waar | opgelost in 8.035 |
register_globals verdient een eigen regel. Jarenlang werd elke parameter in het request, ?admin=1 bijvoorbeeld, een variabele in je script, en als je code $admin controleerde voordat hij was gezet, had de aanvaller hem al voor je gezet. De PHP-handleiding noemde het uitzetten ervan zelf “the most controversial change in PHP”29. Tien jaar van standaard uit tot weg. Zo lang duldde het project een feature waarvan het wist dat hij gevaarlijk was, omdat verwijderen sites zou breken.
Het phar-geval is hetzelfde patroon een laag lager. In 2018 liet Sam Thomas op Black Hat zien dat gewone bestandsoperaties op een phar://-pad door de aanvaller aangeleverde metadata zouden unserialiseren, waarmee het probleem van unserialize() bij functies terechtkwam die niemand als gevaarlijk zag36. PHP 8.0 stopte daar eind 2020 mee als automatisme, “to fix potential security vulnerabilities due to object instantiation, autoloading, etc.”34.
Dan type juggling. De == van PHP zet typen om voordat hij vergelijkt, dus strings die op getallen lijken worden als getallen vergeleken. De RFC die er in PHP 8.0 een deel van oploste zei het zonder omhaal: “This results in many surprising comparison results, the most notable of which is that 0 == ‘foobar’ returns true.”35
Die fix was echt. Hij was ook gedeeltelijk. Hier is dezelfde controle in de officiële containers php:7.4-cli en php:8.5-cli, de tweede is 8.5.12, de release die deze week voor PHP2Shell is gepatcht, met de twee uitkomsten naast elkaar:
$ php -r 'var_dump(0 == "foobar");'
bool(true) # 7.4.33
bool(false) # 8.5.12
$ php -r 'var_dump("0e462097431906509019562988736854" == "0e830400451993494058024219903391");'
bool(true) # 7.4.33
bool(true) # 8.5.12
Twee verschillende strings, gelijk. Beide beginnen met 0e gevolgd door cijfers, dus PHP leest beide als nul maal tien tot een of andere macht, en nul is gelijk aan nul. Beide hebben de vorm van een MD5-hash. Vergelijk een opgeslagen wachtwoordhash met == in plaats van === of hash_equals(), en elke invoer waarvan de hash toevallig zo begint, past. Het is al jaren gedocumenteerd. Het werkt nog steeds in de nieuwste release.
Dat is de taal in één voorbeeld. Een fix die erin ging, de helft van het probleem achtergelaten, en de veilige versie vraagt dat je weet dat er een andere operator bestaat.
Een shell, bijna elk jaar
De vraag die je van elk platform moet stellen is niet hoeveel bugs het heeft gehad. Het is hoe vaak iemand de hele server kon overnemen zonder wachtwoord en zonder dat iemand ergens op klikte.
NVD geeft elke CVE een score. Filter de 757 op de score die precies dat betekent, aanval via het netwerk, geen rechten, geen gebruikersinteractie, hoge impact op vertrouwelijkheid en integriteit, en je houdt er 172 over15.
172, verspreid over 23 van de 28 jaren die überhaupt een PHP-CVE hebben. Maar vijf zijn leeg. 2016 alleen heeft er 65.
Een ernstscore is een beoordeling, geen inbraak. Dus de tweede helft van het beeld is de Known Exploited Vulnerabilities-catalogus van CISA, die alleen fouten opneemt waarvan misbruik in het wild bevestigd is26. Van de 1.754 vermeldingen op 21 oktober 2026 zijn er 81 PHP zelf of applicaties die in PHP geschreven zijn:
| Jaar toegevoegd | PHP en PHP-applicaties | Hele catalogus |
|---|---|---|
| 2021 | 16 | 311 |
| 2022 | 16 | 555 |
| 2023 | 10 | 187 |
| 2024 | 8 | 186 |
| 2025 | 11 | 245 |
| 2026, tot 21 oktober | 20 | 270 |
2026 is nu al het slechtste jaar voor PHP in de catalogus, en PHP2Shell staat er nog niet in. Drie van dit jaar zitten in WordPress-core zelf: twee toegevoegd op 21 juli, en een remote file inclusion op 25 september.
| KEV-vermeldingen waarvan gebruik door ransomware bekend is | Wat |
|---|---|
| CVE-2019-11043 | buffer overflow in PHP-FPM |
| CVE-2024-4577 | argument injection in PHP-CGI |
| CVE-2021-3129 | Laravel Ignition |
| CVE-2018-7600, CVE-2018-7602 | Drupal |
En de catalogus telt PHP flink te laag. Hij is opgezet rond Amerikaanse federale systemen en vereist een CVE plus bevestigd misbruik. Er staan 3 WordPress-plugins in. Het pluginecosysteem van WordPress registreerde in 2025 alleen al 11.334 kwetsbaarheden37. De 81 is het deel dat iemand officieel heeft opgeschreven.
WordPress vermenigvuldigt het
WordPress is 39,6% van alle websites, en 58,3% van de sites waarvan het contentmanagementsysteem te herkennen is38. PHP is de server-side taal van 69,3% van de sites waar dat te zien is39. Dus wat het dossier van PHP ook is, WordPress brengt het naar een heel groot deel van het web, en voegt er dan zijn eigen dossier aan toe.
Core is niet het grootste probleem. De plugins zijn het.
| 2024 | 2025 | |
|---|---|---|
| Nieuwe kwetsbaarheden in het WordPress-ecosysteem, Patchstack | 7.96640 | 11.33437 |
| In plugins | 96% | 91% |
| In core | 7 | 6 |
| Niet op tijd opgelost voor de openbare bekendmaking | 33% | 46% |
| Mediaan tot massaal misbruik, zwaar misbruikte bugs | 5 uur |
Wordfence telde met een eigen database 8.223 voor 2024, een stijging van 68% ten opzichte van 2023, en vond “Roughly 35% of the vulnerabilities disclosed in 2024 remain unpatched in 2025”41. Andere databases, andere totalen, dezelfde vorm.
Sta even stil bij de cijfers van 2025. Bijna de helft van de kwetsbaarheden had geen fix van de ontwikkelaar op het moment dat ze openbaar werden. En voor de bugs waar aanvallers echt op afgaan is de mediaan tussen bekendmaking en massaal misbruik vijf uur. De meeste mensen controleren hun plugin-updates niet elke vijf uur. De meeste mensen kunnen dat niet.
Het pluginmodel is de vermenigvuldiger. De veiligheid van een site hangt af van de minst zorgvuldige auteur van alles wat erop geïnstalleerd is, en Wordfence vond dat “over one third of developers are unreachable or unresponsive” als ze over een fout werden ingelicht41. Patchstack telde 1.614 plugins en thema’s die in 2024 uit de repository zijn gehaald vanwege securityproblemen die niemand oploste40. En door het model met één proces draait elke plugin met de volledige rechten van de site.
De incidenten vormen een lange lijst. Dit zijn de gevallen met primaire bronnen erachter:
| Jaar | Wat | Schaal |
|---|---|---|
| 2011 | TimThumb, een afbeeldingsscript dat in veel thema’s zat, liet aanvallers “upload and execute arbitrary PHP code”42 | “many commercial and free themes” |
| 2014 | RevSlider, achter de SoakSoak-campagne43 | “compromising over 100,000 WordPress sites” |
| 2016 | Mossack Fonseca, het kantoor van de Panama Papers: de site “may have been breached via a vulnerable version of Revolution Slider”44 | de site draaide een misbruikbare versie; hoe de data wegging is nooit aangetoond |
| 2017 | content injection via de REST API in WordPress 4.7.0 en 4.7.1, standaard aan45 | 66.000 door Google geïndexeerde bekladde pagina’s volgens Sucuri46; 1.893.690 volgens Wordfence vier dagen later47 |
| 2020 | WP File Manager, code execution zonder authenticatie, misbruikt voordat er een patch bestond48 | “over 700,000 active installations” |
| 2025 | SureTriggers, aanmaken van een beheerdersaccount zonder authenticatie49 | “exploitation attempts observed within hours after disclosure” |
Met de rij van 2016 ben ik voorzichtig geweest. Wordfence liet zien dat de site van het kantoor een sliderversie draaide die kinderlijk eenvoudig te misbruiken was. Het liet niet zien dat de documenten zo werden weggehaald, en ik ga niet meer beweren dan het bewijs draagt.
Hoe de malware blijft
Binnenkomen is de helft. Binnenblijven is de andere helft, en PHP maakt dat makkelijk om een reden die rechtstreeks teruggaat op het beeld van het ene proces.
De interpreter draait elk .php-bestand dat hij kan bereiken. De webroot is meestal schrijfbaar voor dezelfde gebruiker die de code draait. Dus zodra een aanvaller op welke manier ook een bestand kan schrijven, een uploadformulier, een pluginbug, een bestandsbeheerder, kan hij een script neerzetten dat draait elke keer dat iemand het opvraagt. Dat is een webshell: een klein bestand, in je site, dat commando’s aanneemt.
CISA zegt al jaren in welke talen die meestal geschreven zijn: “The most commonly observed web shells are written in languages that are widely supported, such as PHP and ASP.”50 De gezamenlijke richtlijn van de NSA en het Australian Signals Directorate noemt ze “a long-standing, pervasive threat that continues to evade many security tools”, en moeilijk te ontdekken omdat ze “easily modified by attackers and often employ encryption, encoding, and obfuscation”51.
De opschoningscijfers laten zien hoe vaak ze er zijn:
| Bron | Bevinding |
|---|---|
| Sucuri, 2022, 43.374 sites opgeschoond | “69.63% of compromised websites were found to have at least one backdoor”; 1.188.864 backdoors verwijderd52 |
| Sucuri, 2022 | “90% of credit card skimmers were found in the form of malicious PHP code”52 |
| Sucuri, 2023, 39.594 sites opgeschoond | “49.21% of compromised websites were found with at least one website backdoor”; WordPress 95,5% van de infecties53 |
| Wordfence, 2024 | “just under one million distinct sites infected with malware”41 |
Dus in het meest recente opschoningsjaar had de helft van de gehackte sites nog een weg terug op de schijf staan. Zet de database terug, patch de plugin, en de aanvaller loopt weer binnen via het bestand dat hij achterliet.
Hier bestaat geen slimme oplossing voor. Er is de saaie, fatsoenlijke, en de NSA heeft hem opgeschreven: “web applications should not have permission to write directly to a web accessible directory or modify web accessible code”51. Die ene zin is het model met gescheiden lagen van het begin van deze post, uitgesproken door een inlichtingendienst.
| Waar het misgaat | De maatregel die het tegenhoudt |
|---|---|
| de runtimegebruiker kan de code schrijven | code in bezit van een aparte deploygebruiker, alleen-lezen voor de runtimegebruiker |
| uploads komen binnen de webroot terecht | sla uploads op “outside of the webroot”, of op een andere server54 |
| PHP voert alles in uploads uit | geen scriptuitvoering voor uploadpaden op de webserver, en “disable per directory configuration overrides on upload directories”54 |
| niemand merkt een nieuw bestand op | file integrity monitoring tegen een bekende goede kopie51 |
| het database-account kan alles | least privilege voor de databasegebruiker13 |
De hardeninggids van WordPress, voor wat die waard is, noemt nergens het tegenhouden van PHP-uitvoering in de uploadmap11. Daarom citeert de tabel OWASP en de NSA.
Kijk wat er niet in die tabel staat. De eigen hardeninginstellingen van PHP. De handleiding is daar eerlijk over. disable_functions “can be circumvented and should not be considered a sufficient security measure for shared hosting environments”, en open_basedir “is just an extra safety net, that is in no way comprehensive, and can therefore not be relied upon when security is needed”55. Als de eigen documentatie van een taal je vertelt dat de veiligheidsknoppen geen veiligheidsgrenzen zijn, geloof het dan. Daarom moet de grens van buiten het proces komen.
Zelfs bij php.net werd ingebroken
Als de eigen infrastructuur van het project degelijk was, zou je kunnen stellen dat het dossier neerkomt op een moeilijk probleem dat goed wordt aangepakt. Er is twee keer ingebroken.
| Wanneer | Wat er gebeurde |
|---|---|
| 22 tot 24 oktober 2013 | “JavaScript malware was served to a small percentage of php.net users”; “two servers were compromised”, methode “unknown at this time”56 |
| 28 maart 2021 | “two malicious commits were pushed to the php-src repo” onder de namen van twee kernontwikkelaars57 |
Die van 2021 is degene die telt. Iemand duwde code in de eigen broncodeboom van de taal, en deed zich daarbij voor als de mensen die hem onderhouden. Het werd ontdekt. Het antwoord van het project is het citeren waard, omdat het het juiste is, recht voor zijn raap: “maintaining our own git infrastructure is an unnecessary security risk”, en de repositories verhuisden naar GitHub57.
Eer wie eer toekomt: dat was een goede beslissing, snel genomen en in het openbaar uitgelegd. Maar kijk wat het toegeeft. Jarenlang stond de canonieke broncode van een taal die het grootste deel van het web draait op zelf beheerde infrastructuur waarvan het project zelf vond dat het een risico was dat het niet hoorde te dragen.
De helft van het web draait een versie die niemand patcht
Alles hierboven gaat ervan uit dat de site up-to-date is. Heel veel zijn dat niet.
php.net ondersteunt op dit moment vier takken. 8.2 krijgt alleen nog securityfixes, tot 31 december 2026. 8.3, 8.4 en 8.5 zijn de rest58. Alles wat ouder is, is end of life: 8.1 sinds 31 december 2025, 8.0 sinds november 2023, 7.4 sinds november 202259.
Nu het gemeten aandeel van wat er echt draait:
| Zonder support vandaag | Zonder support vanaf 1 januari 2027 | |
|---|---|---|
| PHP-sites, W3Techs6061 | 48,3% | ongeveer 66% |
| WordPress-installaties, wordpress.org62 | 34,7% | ongeveer 58% |
PHP 7.4 alleen, al bijna vier jaar zonder support, is ongeveer een vijfde van alle PHP-sites die hun versie laten zien. De vereistenpagina van WordPress zelf vraagt om PHP 8.3, en zegt dan dat WordPress “also works with PHP 7.4+”, terwijl het opmerkt dat die versies “have reached their official End Of Life”63. Een leverancier die nog op een dode versie draait, is een leverancier die heeft besloten je niet te laten overstappen.
Twee eerlijke kanttekeningen. W3Techs ziet de versie alleen op sites die hem tonen. En sommige Linux-distributies backporten fixes in oude PHP-builds, dus “niet ondersteund door php.net” is niet altijd “niet gepatcht”. Maar PHP2Shell is daar de test van. Het project heeft deze keer wel bronpatches voor 7.4, 8.0 en 8.1 gepubliceerd1, en iemand moet ze nog steeds bouwen, uitleveren en installeren. Op een shared host met een versie waar niemand eigenaar van is, is die iemand niemand.
Ik ben ermee gestopt. Jij zou ook moeten overwegen te vertrekken.
Ik schreef vroeger PHP. Na Pulsant ben ik met de taal gestopt, vanwege de problemen die hij veroorzaakte en het werk dat die problemen opleverden. Niet één slecht incident. Jaren van dezelfde twee oorzaken, site na site, en het opruimwerk dat terechtkwam bij wie er toevallig dienst had.
Dus ik zeg het zonder omwegen. Als de keuze aan jou is, overweeg dan te vertrekken. Er zijn hier nu betere middelen voor, en Go is degene waar ik je als eerste op zou wijzen.
Niet omdat het in de mode is. Omdat het standaard het meeste weghaalt van wat deze post heeft zitten tellen:
| De gebruikelijke PHP-site | Een Go-service | |
|---|---|---|
| Geheugenveiligheid | engine in C geschreven, 288 CVE’s met geheugencorruptie | geheugenveilig door ontwerp; de NSA en CISA noemen het allebei1819 |
| De code draaien | bij elk request opnieuw geparsed en gecompileerd, tenzij OPcache geladen is, een extensie die je vóór 8.5 zelf toevoegt; daarna uitgevoerd door een interpreter in C; een JIT sinds 8.0, standaard uit6465 | één keer gecompileerd, vooraf, naar native machinecode66 |
| Een request afhandelen | de webserver geeft elk request door aan een interpreter | één gecompileerde binary beantwoordt HTTP zelf |
| Een bestand gedropt in de webroot | een .php-bestand draait zodra iemand het opvraagt | niets draait een bestand van schijf vanwege zijn pad |
| HTML-uitvoer | echo schrijft rauw; escapen is een functie die je moet onthouden | html/template escapet standaard, per context67 |
| SQL | prepared statements bestaan in PDO, als je ze gebruikt | de gedocumenteerde manier geeft parameters mee als argumenten68 |
| Bekende fouten in waar je van afhangt | hoor je via het nieuws | govulncheck meldt alleen degene die je code echt aanroept69 |
| Waar de onderdelen staan | code, config en uploads in één schrijfbare boom | een alleen-lezen binary, met config en uploads ergens anders |
Gecompileerd telt twee keer. Het is sneller: Go-programma’s “are compiled ahead of time to native machine code”, zonder virtuele machine eronder, en een van de uitgesproken ontwerpdoelen is “to approach the performance of C for comparable programs”66. En het is veiliger, want er zit geen interpreter in het requestpad die tijdens het draaien code parset, en geen C-engine met 757 CVE’s tussen het netwerk en je programma. PHP doet, aan zichzelf overgelaten, het omgekeerde. Zonder OPcache laadt, parset en compileert het elk script bij elk request, nodeloos, duizenden keren per minuut op een drukke site. OPcache bestaat om dat te stoppen, “removing the need for PHP to load and parse scripts on each request”64. Maar het staat niet standaard aan. Tot en met 8.4 is het een aparte gedeelde extensie die iemand met zend_extension moet laden en configureren. Pas PHP 8.5 bouwt het in: “The Opcache extension is now always built into the PHP binary and is always loaded”70. De eigen RFC van het project voor die wijziging zegt “running PHP in production without OPcache is generally considered a mistake”71. W3Techs zet 8.5 op 4,5% van de PHP 8-sites60, dus voor bijna alles wat vandaag draait is de oplossing voor het compileren van elk script bij elk request nog steeds een add-on die iemand moest onthouden. En zelfs geladen is wat het cachet bytecode die de C-interpreter moet uitvoeren. Go doet het compileren één keer, voordat het programma ooit een request ziet.
Sneller en veiliger, op voorwaarde dat het fatsoenlijk is geprogrammeerd. Die laatste bijzin is het hele onderwerp van de volgende alinea’s.
Het templatepakket van Go zet zijn ontwerp in één regel neer: het genereert “HTML output safe against code injection”, en “The escaping is contextual, so actions can appear within JavaScript, CSS, and URI contexts.”67 De databasegids is net zo duidelijk: “You can avoid an SQL injection risk by providing SQL parameter values as sql package function arguments.”68 Dat zijn de standaarden. In PHP zijn het dingen waarvan je moet weten dat je ze moet gaan halen.
De rij die ik zou onderstrepen is het gedropte bestand. De helft van de gehackte sites die Sucuri in 2023 opschoonde had nog een backdoor op schijf53, en dat werkt alleen omdat de interpreter elk script draait dat hij kan bereiken. Een gecompileerde service gaat niet op zoek naar scripts. Er is helemaal niets waar een gedropt bestand op kan inprikken.
Nu het eerlijke deel, want een taal is geen geneesmiddel. Go is geheugenveiliger, niet volmaakt. Het eigen geheugenmodel zegt dat een data race op een slice, een map of een interfacewaarde “can in turn lead to arbitrary memory corruption”72, en Go levert het gereedschap om die te vangen. Bouw met -race, of draai go test -race, en de binary wordt gecompileerd met een detector die een race meldt op het moment dat hij gebeurt. Hij vangt races tijdens het draaien in plaats van bij het compileren, en “can’t find races in code paths that are not executed”, dus hij hoort in elke testrun en onder een realistische belasting73. PHP heeft niets vergelijkbaars. Het geheugen van het ene request weghouden van het volgende wordt volledig aan de engine overgelaten, en PHP2Shell is die engine die het fout doet: geheugen vrijgegeven door het ene request, gelezen door het volgende op dezelfde worker6. Daarbuiten houdt Go de klasse geheugencorruptie tegen die deze post heeft zitten tellen, en maakt het de veilige weg de makkelijke weg voor nog twee. Het houdt geen kapotte logincontrole tegen, geen ontbrekende rechtencontrole en geen query die aan elkaar is geplakt uit strings als je daar per se op staat. Go publiceert ook zijn eigen security-advisories, via zijn kwetsbaarhedendatabase69. En een Go-service die als root draait vanuit een schrijfbare map is nog steeds slecht ingericht.
Wat het verandert is de standaard. De standaard van PHP is één proces dat alles vasthoudt. De standaard van Go is een programma dat één taak doet, en dat is de splitsing van het begin van deze post met het meeste werk al gedaan. Als Go niet bij je team past, is Rust de andere uitweg. Beide worden vooraf naar native machinecode gecompileerd. Rust draait “with no runtime or garbage collector”74, en de compiler en runtime van Go zijn sinds Go 1.5 “implemented in Go and assembler, without C”75.
C# en Java staan ook op de lijst van geheugenveilige talen van de diensten18, maar ze zijn geen uitweg uit het probleem waar deze post mee begon. Allebei draaien ze op een virtuele machine die in C++ is geschreven. HotSpot van OpenJDK beslaat “around 3000 C/C++ header and source files, comprising more than 1.2 million lines of code”76, en de garbage collector en JIT-compiler van .NET zijn C++-broncode in de CoreCLR-boom77. Dat is dezelfde vorm als bij PHP: een grote native engine tussen het netwerk en jouw code. En Java laadt bewust code in een draaiende applicatie. De standaard-classloader is er “to load classes and resources from a search path of URLs referring to both JAR files and directories”78, en Log4Shell maakte daar remote code execution van: wie een logbericht in handen had, “can execute arbitrary code loaded from LDAP servers”79. Het lek ging regelrecht de catalogus van CISA in26. Het is dezelfde deur als bij PHP, met meer ceremonie ervoor.
Kies dus Go of Rust. Verhuis eerst de back end, één endpoint tegelijk, en laat de PHP-front end niets houden dat het stelen waard is totdat die ook weg kan.
Als je het nog steeds zo inricht, kun je jezelf dan een professional noemen?
Er staat genoeg bewijs hierboven om dit niet langer een mening te laten zijn. Dus hier is de vraag, recht op de man af. Als je PHP nog steeds inricht als één proces dat de code, de credentials en een schrijfbare webroot vasthoudt, kun je jezelf dan een professional noemen?
Het hangt ervan af welke van drie mensen je bent. En weten welke is niet iets wat je overkomt. Ervoor zorgen dat je het weet, is het werk.
Je hebt een echte beperking, en je hebt hem opgeschreven. Een product waar het bedrijf van afhangt bestaat alleen in PHP. Een migratie is begroot en staat in het budget van volgend jaar. Prima. Dat is professioneel, op voorwaarde dat de reden op papier staat met een datum ernaast, de runtimegebruiker de code niet kan schrijven, uploads niet kunnen uitvoeren, het database-account is ingeperkt, en je deze week PHP2Shell hebt gepatcht. Je draait bewust een bekend risico, met de muren die je eromheen kunt zetten.
Niemand heeft het je ooit verteld. Niemand liet je het dossier zien, en de tutorial waarvan je het leerde zette alles in één map. Dat is een gat, en iedereen heeft gaten. Het houdt op een gat te zijn op het moment dat je tot hier hebt gelezen.
Je weet het, en je bouwt het toch. Je hebt de cijfers gezien, of genoeg ervan. Je weet dat het databasewachtwoord in de webroot staat en dat de webroot schrijfbaar is. Je richt het zo in omdat het sneller is, omdat de klant niet voor beter wil betalen, en omdat niemand je heeft laten verantwoorden waarom. Op dat geval is deze vraag gericht. Het falen is niet het gat in je kennis. Het is over een gat heen bouwen dat je al hebt gezien en nooit bent teruggegaan om te dichten.
Iedereen heeft daar ooit gestaan. Er uit eigen keuze blijven staan is het deel dat niet te verdedigen is.
De deur stond altijd open
Wat me opvalt als ik dit dossier lees, is niet dat PHP bugs heeft. Elke taal heeft die. Het is hoe weinig ervan ooit een verrassing was.
Het project wist in 2002 dat register_globals gevaarlijk was en haalde het in 2012 weg. De handleiding zegt je unserialize() niet te vertrouwen, disable_functions niet te vertrouwen, open_basedir niet te vertrouwen. De eigen documentatie zegt dat een script onder mod_php zonder wachtwoord bij de database kan. De diensten zeggen al jaren dat de taal waarvan het gebouwd is de plek is waar twee derde van de geheugenbugs vandaan komt. Elke waarschuwing staat er, op schrift, van de mensen die het zouden moeten weten.
En het bleef toch winnen, omdat het goedkoop was. Goedkoop om te hosten, goedkoop om te leren, goedkoop om te verkopen aan een klant die vrijdag een website wilde. Eén map, één proces, één wachtwoord in een bestand, en een site die werkte. Waarvoor het geprijsd stond was een shared hostingpakket. Wat het kostte stond nooit op de factuur: het opruimwerk, de backdoors die op schijf achterbleven, de kaartnummers van klanten die door kwaadaardige PHP werden weggehaald, het venster van vijf uur tussen bekendmaking en aanval.
Dat is het deel waar ik geen geduld voor heb. Niet de bugs. De beslissing, keer op keer genomen door mensen die beter wisten, dat de goedkope manier goed genoeg was omdat niemand controleerde. Een standaard is wat je aanhoudt als niemand controleert. De splitsing tussen front end en back end, de alleen-lezen code, het ingeperkte database-account: niets daarvan is nieuw, niets daarvan is duur, en alles samen had een flink deel van de incidenten hierboven veranderd in niets wat het opschrijven waard was.
PHP2Shell is niet het einde van dit dossier. Het is alleen de vermelding van deze week. De taal zal het patchen, de hosts zullen de update uiteindelijk uitrollen, en het versieaandeel schuift omhoog zoals altijd, langzaam. Wat bepaalt of de volgende jou iets kost, is niet PHP. Het is of je de muren hebt gebouwd die het je nooit gaf, of bent overgestapt naar iets waar ze bij zitten.
PHP — News archive 2026, 21st October — “PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix two critical vulnerabilities that can allow unauthenticated remote code execution”; “We consider the risk highest for mod_php, with a demonstrated exploit where an unauthenticated request can trigger the attack before any application code runs”; “There are no complete mitigations, updating is the only safe choice.” ↩︎ ↩︎ ↩︎
Wiz Research — PHP2Shell — 21 oktober 2026; “Every PHP version released in the last decade is affected by at least one of these vulnerabilities, going back to version 5.4”; “All of the disclosed vulnerabilities are memory-safety issues”. ↩︎
AWS Security Blog — PHP2Shell exploitation prior to public disclosure in MadPot — een misbruikpoging geregistreerd op 17 oktober 2026. ↩︎
watchTowr — PHP2Shell FAQ — misbruik in het wild waargenomen op 21 oktober 2026. ↩︎
NVD — CVE-2026-109618 — de afhandeling van een out-of-memoryfout laat deels geïnitialiseerde requestdata achter die de opruimcode als geldig behandelt; remote code execution. ↩︎
NVD — CVE-2026-109619 — requestgeheugen gebruikt nadat het is vrijgegeven; remote code execution; getroffen vanaf 5.4.0. ↩︎ ↩︎
PHP manual — Installed as an Apache module — “When PHP is used as an Apache module it inherits Apache’s user permissions”; “a malicious script could access and modify the database, even without a username and password”. ↩︎
PHP manual — Apache 2.x on Unix systems — “The mod_php approach embeds PHP directly into every Apache httpd worker process.” ↩︎ ↩︎
WordPress — wp-config.php — staat in de root van de WordPress-map en bevat de gegevens voor de databaseverbinding. ↩︎
WordPress — Changing file permissions — wp-config.php “is initially created with 644 permissions, and it’s a hazard to leave it like that”. ↩︎
WordPress — Hardening WordPress — databaserechten, bestandsrechten; geen richtlijn voor het blokkeren van PHP-uitvoering in uploads. ↩︎ ↩︎
OWASP — Database Security Cheat Sheet — “The application’s backend database should be isolated from other servers”; een apart intern netwerksegment. ↩︎
PHP manual — Database design — “Applications should never connect to the database as its owner or a superuser.” ↩︎ ↩︎
PHP manual — FastCGI Process Manager — pools die workers starten “with different uid/gid/chroot/environment”. ↩︎
NVD CVE API,
virtualMatchString=cpe:2.3:a:php:php— opgevraagd op 23 oktober 2026: 757 CVE’s. Geheugencorruptie geteld als CWE-119, 120, 121, 122, 125, 129, 131, 189, 190, 191, 415, 416, 476, 680, 787, 824, 843 of 908: 288. Volledige overname op afstand geteld als CVSS 3.xAV:N/PR:N/UI:N/C:H/I:H, of CVSS 2 netwerk, geen authenticatie, volledige impact op vertrouwelijkheid en integriteit waar geen 3.x-score bestaat: 172. ↩︎ ↩︎Month of PHP Bugs, php-security.org, Wayback Machine — “During March 2007 old and new security vulnerabilities in the Zend Engine, the PHP core and the PHP extensions will be disclosed on a day by day basis.” ↩︎
The Register — Stefan Esser interview, 7th February 2007 — oprichter van het Hardened-PHP Project, onlangs vertrokken bij het PHP Security Response Team: “I dislike the ways bugs are handled”. ↩︎
NSA — Software Memory Safety, November 2022, Wayback Machine — “a strategic shift from programming languages that provide little or no inherent memory protection, such as C/C++, to a memory safe language when possible.” Ook: “Examples of memory safe language include C#, Go, Java®, Ruby™, Rust®, and Swift®.” ↩︎ ↩︎ ↩︎
CISA and partners — The Case for Memory Safe Roadmaps, December 2023 — onder meer samen met het Britse NCSC geschreven; “two-thirds of reported vulnerabilities in memory unsafe programming languages still relate to memory issues.” ↩︎ ↩︎
NVD — CVE-2014-8142 — use-after-free in
process_nested_datatijdens unserialize. ↩︎NVD — CVE-2015-0231 — use-after-free in unserialize die “exists because of an incomplete fix for CVE-2014-8142”. ↩︎
NVD — CVE-2016-5771 — use-after-free in SPL, uitgelokt via unserialize en garbage collection. ↩︎
PHP manual — unserialize — “Do not pass untrusted user input to unserialize() regardless of the options value of allowed_classes.” ↩︎
NVD — CVE-2019-11043 — “in certain configurations of FPM setup it is possible to cause FPM module to write past allocated buffers … opening the possibility of remote code execution.” ↩︎
PHP 7 ChangeLog — opgelost op 24 oktober 2019 in 7.3.11, 7.2.24 en 7.1.33, bug #78599. ↩︎
CISA — Known Exploited Vulnerabilities catalogue — JSON-feed versie 2026.10.21, 1.754 vermeldingen; 81 voor PHP of in PHP geschreven applicaties naar leverancier en product; gebruik door ransomware zoals vastgelegd in de feed. ↩︎ ↩︎ ↩︎
The PHP Foundation — PHP core security audit results, 10th April 2025 — “The audit identified 27 issues, with 17 having security implications”. ↩︎
PHP 4 ChangeLog — 4.2.0, 22 april 2002: “register_globals defaults to ‘off’ now”. ↩︎
PHP manual — Using Register Globals, Wayback Machine — “DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0”; “the most controversial change in PHP”. ↩︎ ↩︎
PHP manual — Magic Quotes, Wayback Machine — “DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0”. ↩︎
PHP manual — Deprecated features in PHP 5.5.x, Wayback Machine — “The preg_replace() /e modifier is now deprecated.” ↩︎
PHP manual — Pattern Modifiers, Wayback Machine —
e“DEPRECATED in PHP 5.5.0, and REMOVED as of PHP 7.0.0.” ↩︎PHP manual — Deprecated features in PHP 7.4 — “The allow_url_include ini directive is deprecated.” ↩︎
PHP manual — Backward incompatible changes in PHP 8.0 — phar-metadata “will no longer be automatically unserialized, to fix potential security vulnerabilities due to object instantiation, autoloading, etc.” ↩︎ ↩︎
PHP RFC — Saner string to number comparisons — geïmplementeerd in PHP 8.0; “the most notable of which is that 0 == ‘foobar’ returns true.” ↩︎ ↩︎
Sam Thomas, Black Hat USA 2018 — It’s A PHP Unserialization Vulnerability Jim, But Not As We Know It — bestandsoperaties op
phar://-paden unserialiseren metadata. ↩︎Patchstack — State of WordPress Security in 2026 — cijfers over 2025: 11.334 nieuwe kwetsbaarheden, 91% plugins, 6 in core, 46% niet op tijd opgelost voor de bekendmaking, mediaan 5 uur tot massaal misbruik. ↩︎ ↩︎
W3Techs — WordPress — “58.3% of all the websites whose content management system we know. This is 39.6% of all websites.” ↩︎
W3Techs — PHP — “PHP is used by 69.3% of all the websites whose server-side programming language we know.” Gelezen op 23 oktober 2026. Hoofdversies onder PHP-sites: 8 op 65,3%, 7 op 26,9%, 5 op 7,7%. ↩︎
Patchstack — State of WordPress Security in 2025 — cijfers over 2024: 7.966 nieuwe kwetsbaarheden, 96% plugins, 7 in core, 33% niet op tijd opgelost voor de bekendmaking. ↩︎ ↩︎
Wordfence — 2024 Annual WordPress Security Report — 8.223 kwetsbaarheden, een stijging van 68%; “Roughly 35% of the vulnerabilities disclosed in 2024 remain unpatched in 2025”; “just under one million distinct sites infected with malware”. ↩︎ ↩︎ ↩︎
Mark Maunder — Zero day vulnerability in many WordPress themes, 1st August 2011 — timthumb.php meegeleverd met “many commercial and free themes”; aanvallers konden “upload and execute arbitrary PHP code”. ↩︎
Sucuri — RevSlider vulnerability leads to massive WordPress SoakSoak compromise, 15th December 2014 — “compromising over 100,000 WordPress sites”. ↩︎
Wordfence — Mossack Fonseca breach, Revolution Slider possible cause, 7th April 2016, Wayback Machine — “may have been breached via a vulnerable version of Revolution Slider”. ↩︎
Sucuri — Content injection vulnerability in WordPress REST API, 1st February 2017 — “allows an unauthenticated user to modify the content of any post or page”; standaard aan in 4.7.0 en 4.7.1. ↩︎
Sucuri — WordPress REST API vulnerability abused in defacement campaigns, 6th February 2017 — “Google alone shows 66,000+ pages compromised”, voor één campagne. ↩︎
Wordfence — Rapid growth in REST API defacements, 10th February 2017, Wayback Machine — door Google geïndexeerde bekladde pagina’s groeiden “from 1,496,020 to 1,893,690”; de eerdere telling van Sucuri was 66.000. ↩︎
Wordfence — 700,000 WordPress users affected by zero-day in File Manager plugin, 1st September 2020, Wayback Machine — “a WordPress plugin with over 700,000 active installations”. ↩︎
Patchstack — SureTriggers vulnerability exploited within 4 hours, 10th April 2025 — aanmaken van een beheerder zonder authenticatie; “exploitation attempts observed within hours after disclosure”. ↩︎
CISA — Compromised Web Servers and Web Shells, TA15-314A — “The most commonly observed web shells are written in languages that are widely supported, such as PHP and ASP.” ↩︎
NSA and ASD — Detect and Prevent Web Shell Malware, April 2020, Wayback Machine — “web applications should not have permission to write directly to a web accessible directory or modify web accessible code”; file integrity monitoring als terugvaloptie. ↩︎ ↩︎ ↩︎
Sucuri — 2022 Website Threat Research Report — 43.374 sites opgeschoond; 69,63% met minstens één backdoor; 1.188.864 backdoors verwijderd; 90% van de kaartskimmers in kwaadaardige PHP. ↩︎ ↩︎
Sucuri — 2023 Hacked Website and Malware Threat Report — 39.594 sites opgeschoond; 49,21% met minstens één backdoor; WordPress 95,5% van de infecties. ↩︎ ↩︎
OWASP — File Upload Cheat Sheet — sla uploads op “outside of the webroot”; “disable per directory configuration overrides on upload directories”. ↩︎ ↩︎
PHP manual — Description of core php.ini directives —
disable_functions“can be circumvented”;open_basedir“can therefore not be relied upon when security is needed”. ↩︎PHP — News archive 2013, 24th October — malware uitgeleverd van 22 tot 24 oktober 2013; twee servers gecompromitteerd. ↩︎
PHP internals — Changes to Git commit workflow, 28th March 2021 — twee kwaadaardige commits in php-src geduwd; de git.php.net-server stopgezet en GitHub canoniek gemaakt. ↩︎ ↩︎
PHP — Supported versions — 8.2 securityfixes tot 31 december 2026; 8.3, 8.4 en 8.5 ondersteund. Gelezen op 23 oktober 2026. ↩︎
PHP — Unsupported branches — 8.1 end of life 31 december 2025, 8.0 26 november 2023, 7.4 28 november 2022. ↩︎
W3Techs — PHP version 8 — aandelen van subversies binnen PHP 8; gecombineerd met de aandelen per hoofdversie geeft dat 48,3% van de PHP-sites op versies zonder support. ↩︎ ↩︎
W3Techs — PHP version 7 — 7.4 is 73,4% van de PHP 7-sites. ↩︎
WordPress — Statistics — PHP-versies van WordPress-sites die aan wordpress.org rapporteren; 34,7% onder 8.2. Gelezen op 23 oktober 2026. ↩︎
WordPress — Requirements — “PHP version 8.3 or greater”; werkt met 7.4+, die “reached their official End Of Life” hebben. ↩︎
PHP manual — OPcache introduction — “OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request.” Tot en met PHP 8.4 een gedeelde extensie die via
zend_extensionwordt geladen. ↩︎ ↩︎PHP manual — OPcache runtime configuration —
opcache.jitbeschikbaar vanaf PHP 8.0.0, standaard “disable”. ↩︎Go — Frequently Asked Questions — “Go programs are compiled ahead of time to native machine code”; de runtime “does not include a virtual machine”; “One of Go’s design goals is to approach the performance of C for comparable programs”. ↩︎ ↩︎
Go — package html/template — “implements data-driven templates for generating HTML output safe against code injection”; “The escaping is contextual, so actions can appear within JavaScript, CSS, and URI contexts.” ↩︎ ↩︎
Go — Avoiding SQL injection risk — “You can avoid an SQL injection risk by providing SQL parameter values as
sqlpackage function arguments.” ↩︎ ↩︎Go — Vulnerability management — een beheerde kwetsbaarhedendatabase; govulncheck “only surfaces vulnerabilities that actually affect you, based on which functions in your code are transitively calling vulnerable functions”. ↩︎ ↩︎
PHP manual — Backward incompatible changes in PHP 8.5 — “The Opcache extension is now always built into the PHP binary and is always loaded. The INI directives opcache.enable and opcache.enable_cli are still honored.” ↩︎
PHP RFC — Make OPcache a non-optional part of PHP — geïmplementeerd in PHP 8.5; “running PHP in production without OPcache is generally considered a mistake”. ↩︎
Go — The Go Memory Model — races op waarden van meerdere woorden “can in turn lead to arbitrary memory corruption”; ThreadSanitizer via
go build -racemeldt races. ↩︎Go — Data Race Detector — draai tests met
go test -race; “The race detector only finds races that happen at runtime, so it can’t find races in code paths that are not executed.” ↩︎Rust — rust-lang.org — “Rust is blazingly fast and memory-efficient: with no runtime or garbage collector”. ↩︎
Go 1.5 Release Notes — “The compiler and runtime are now implemented in Go and assembler, without C.” ↩︎
OpenJDK — The HotSpot Group — “around 3000 C/C++ header and source files, comprising more than 1.2 million lines of code”. ↩︎
dotnet/runtime — src/coreclr — de garbage collector (
gc/gc.cpp) en de JIT (jit/compiler.cpp) zijn C++. ↩︎Java SE 21 — URLClassLoader — “to load classes and resources from a search path of URLs referring to both JAR files and directories”. ↩︎
NVD — CVE-2021-44228 — “An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers”; op 10 december 2021 aan de CISA-KEV toegevoegd. ↩︎