Kort gezegd: Wie afhankelijkheden wil bijwerken, heeft een proces nodig voor drie pakketwerelden: Composer-pakketten in de PHP-code, npm-modules in de frontendbuild en plug-ins of thema's in het CMS. Daarbij horen een vast ritme, een verantwoordelijke persoon, tests vóór het uitrollen en een plan voor pakketten zonder update. Tegen PHP2Shell helpt dat niet, want die kwetsbaarheid zit in PHP zelf, maar wel tegen de vele kwetsbaarheden in vreemde code.
Drie pakketwerelden, één blinde vlek
In de week na 21-10-2026 draaide alles om de PHP-interpreter. Veel teams merkten daarbij dat ze de versies van hun eigen bouwstenen niet precies kennen. De website draait, het bureau zorgt ervoor, de plug-in meldt zich wel als er iets nieuws is: zo of ongeveer zo luiden de aannames, totdat iemand gaat kijken.
Een typisch PHP-project bestaat tegenwoordig uit veel meer vreemde dan eigen code. De OWASP Top 10 noemt kwetsbare en verouderde componenten als eigen risicocategorie. Het probleem is zelden het ontbrekende hulpmiddel, maar de ontbrekende routine: updates gebeuren wanneer iemand tijd heeft en beveiligingsmeldingen belanden in een mailbox die niemand leest.
Welke afhankelijkheden werkt u waar bij?
Elke pakketwereld heeft eigen hulpmiddelen en eigen valkuilen. Het volgende overzicht helpt niets over het hoofd te zien.
| Pakketwereld | Bestand tonen | Kwetsbaarheden controleren | Typische valkuil |
|---|---|---|---|
| Composer (PHP-bibliotheken) | composer show |
composer audit |
indirecte pakketten die niemand kent |
| npm (frontendbuild) | npm ls |
npm audit |
update zonder nieuwe build bereikt de server nooit |
| CMS-plug-ins en thema's | beheerinterface of CLI | meldingen van de fabrikant, beveiligingsdiensten | opgegeven plug-ins, betaalde plug-ins zonder updatekanaal |
| PHP en extensies | pakketbeheer | security-tracker van de distributie | getoonde versie zegt weinig over backports |
De laatste regel hoort strikt genomen niet bij de afhankelijkheden van de applicatie, maar wordt vaak in dezelfde adem vergeten. Hetzelfde geldt voor scripts die rechtstreeks van vreemde servers worden ingesloten, zoals bibliotheken uit een CDN, chatwidgets of trackingcode. Ze verschijnen in geen enkel lockbestand, maar draaien wel in de browser van uw bezoekers. Neem ze op in de lijst en controleer of vaste versies zijn ingesloten in plaats van "altijd de nieuwste". De details over composer audit, lockbestand en integratie in de build staan in de gids Composer-afhankelijkheden op kwetsbaarheden controleren. Hoe Composer in de basis werkt, legt Composer: het pakketbeheer voor PHP uit.
De onderhoudscyclus in zes stappen
Een draagkrachtig proces hoeft niet ingewikkeld te zijn. Deze volgorde heeft zich bewezen:
- Bestand vastleggen: Voor elk project een lijst van de directe afhankelijkheden met versie, herkomst en doel. Lockbestanden (
composer.lock,package-lock.json) horen in de repository. - Meldingen verzamelen: Controlehulpmiddelen draaien bij elke build en bovendien regelmatig op de uitgeleverde stand, ook zonder codewijziging.
- Beoordelen: Wordt het getroffen pakket in productie gebruikt, is de getroffen functie bereikbaar, bestaat er een verholpen versie?
- In staging bijwerken en testen: Eerst beveiligingsupdates binnen dezelfde hoofdversie, sprongen naar nieuwe hoofdversies als eigen project plannen.
- Uitrollen met terugweg: De vorige stand blijft beschikbaar als pakket of release, databaseback-up vóór de update.
- Documenteren: Wat is wanneer bijgewerkt, wat bewust niet en waarom.
Let daarbij op de versieopgaven in composer.json en package.json. Te strakke voorschriften verhinderen dat beveiligingscorrecties überhaupt kunnen worden geïnstalleerd. Te ruime voorschriften halen daarentegen ongecontroleerd nieuwe hoofdversies in het project. Het heeft zich bewezen updates binnen de hoofdversie toe te staan en de sprong naar de volgende bewust te plannen.
Voor plug-ins in het CMS zijn beschikbare updates vaak ook op de opdrachtregel te tonen, bij WordPress bijvoorbeeld met WP-CLI:
# Beschikbare updates tonen zonder iets te wijzigen
wp plugin list --update=available
wp theme list --update=available
# Frontendpakketten: verouderde versies en bekende kwetsbaarheden
npm outdated
npm audit --omit=dev
Automatische plug-inupdates rechtstreeks op het productiesysteem zijn handig, maar riskant als niemand daarna controleert. Schakel ze alleen in als vóór elke run een back-up en daarna een controle zijn gewaarborgd.
Als er geen update is
Niet elke melding is met één klik op te lossen. De OWASP Cheat Sheet over het omgaan met kwetsbare afhankelijkheden onderscheidt meerdere gevallen, die goed op het dagelijks werk zijn over te brengen:
- Patch beschikbaar: in staging doorvoeren, testen, uitrollen. Gaat er iets stuk, pas dan de eigen code aan in plaats van de update te laten liggen.
- Patch aangekondigd, maar er nog niet: workaround van de fabrikant doorvoeren, de getroffen functie waar mogelijk uitschakelen of afschermen, beslissing vastleggen.
- Geen patch te verwachten: vervangend pakket zoeken of de fix zelf terugporten, met een test die de kwetsbaarheid vóór en na de patch onderscheidt.
Bij CMS-plug-ins komt vaak een vierde geval voor: de plug-in is opgegeven. Dan helpt alleen vervanging of verwijdering. Hetzelfde geldt voor plug-ins uit onduidelijke bronnen, zoals "gratis" kopieën van betaalde plug-ins. Ze krijgen geen updates via het officiële kanaal en bevatten niet zelden zelf schadelijke code. Aanwijzingen voor WordPress-beheerders bundelt WordPress en PHP2Shell.
Verantwoordelijkheid regelen voordat de volgende melding komt
De meest voorkomende reden voor verouderde pakketten is geen technische hindernis, maar een open vraag: wie doet het? Bij projecten die een bureau heeft gebouwd en die intern worden beheerd, voelt zich vaak niemand verantwoordelijk. Leg voor elk project vast wie meldingen ontvangt, wie beoordeelt en wie vrijgeeft, en schrijf het op.
Plan bovendien tijd in. Een vaste onderhoudsafspraak per maand waarop afhankelijkheden worden gecontroleerd en bijgewerkt, voorkomt dat updates zich jarenlang opstapelen. Hoe langer een project niet is bijgewerkt, des te groter en risicovoller wordt de volgende sprong. Hoe updates van PHP en pakketten in een overkoepelend proces passen, beschrijft Patchbeheer als proces in plaats van brandweer.
Hoe helpt PHP SOS concreet?
- Wij inventariseren alle afhankelijkheden van uw projecten uit Composer, npm en CMS en markeren verouderde, kwetsbare en opgegeven pakketten.
- Wij richten automatische controles in en leggen vast wie welke melding beoordeelt.
- Wij werken bij in staging, testen de belangrijkste processen en rollen uit met terugweg.
- In het kader van een beveiligingsonderhoudscontract nemen wij de maandelijkse cyclus blijvend over, inclusief PHP-updates.
Conclusie: Actuele afhankelijkheden zijn geen project, maar routine. Wie bestand, ritme en verantwoordelijkheid eenmaal netjes regelt, hoeft bij de volgende grote melding alleen nog te controleren en niet eerst te zoeken.
Veelgestelde vragen
Hoe vaak moet men afhankelijkheden bijwerken?
Beveiligingsupdates zo snel mogelijk na beoordeling, routine-updates in een vast ritme, bijvoorbeeld maandelijks. Belangrijker dan de exacte frequentie is dat de afspraak vaststaat en iemand ervoor verantwoordelijk is.
Beschermt een actuele plug-in tegen PHP2Shell?
Nee. PHP2Shell zit in de PHP-interpreter zelf. Daartegen helpt alleen een PHP-update met herstart van alle PHP-processen. Actuele plug-ins en pakketten blijven toch belangrijk, omdat ze eigen kwetsbaarheden dichten.
Wat doe ik met een plug-in die niet meer wordt onderhouden?
Vervangen of verwijderen. Een opgegeven plug-in krijgt geen correcties meer, ook als hij vandaag nog werkt. Tot de vervanging moet u nagaan of de functie echt nodig is en de beslissing documenteren.
Moet de frontend met npm ook op de server worden bijgewerkt?
Vaak zitten npm-pakketten alleen in de build en komen ze als kant-en-klare bestanden op de server. Een kwetsbaarheid in een pakket kan toch in het uitgeleverde JavaScript zitten. Na een update moet daarom opnieuw worden gebouwd en uitgeleverd.