Blog
WordPress-audit? Begin met je plugins
Stop met het auditen van de WordPress-kern en begin met het auditen van je plugins: een praktische, plugin-gerichte beveiligingsaudit voor kleine teams.
Samenvatting
De meeste WordPress-beveiligingsaudits zijn achterstevoren: ze benadrukken kernupdates en scannerrapporten, terwijl de kwetsbaarheden die echt schade aanrichten in plugins zitten. Een witboek van SANS wees uit dat meer dan 96% van de kwetsbaarheden in het ecosysteem afkomstig is van plugins van derden, en ruwweg 43% heeft geen authenticatie nodig. Dit artikel neemt je mee door een audit die bij plugins begint, voor een klein intern marketingteam, aan de hand van het verhaal van een site die werd gehackt omdat iedereen naar de verkeerde laag keek. Je leert elke plugin te inventariseren en classificeren, niet-geauthenticeerde aanvalsoppervlakken te testen, handmatig gebruikers en logboeken te controleren, en bevindingen te vertalen naar een risicotaal die een niet-technische baas begrijpt. Het resultaat is een kwartaalritueel van triage in plaats van een hokjesoefening.
De meeste WordPress-beveiligingsaudits zijn theater. Je besteedt een middag aan het bijwerken van de kern, het wijzigen van het beheerderswachtwoord en het draaien van een plugin-scanner die trots meldt: "Geen kritieke problemen." Ondertussen zit de plugin die bestandsuploads accepteerde en drie jaar geleden voor het laatst is bijgewerkt stil in je uploads-map te wachten op iemand die niet op de gastenlijst staat.
De cijfers bevestigen dit. Een witboek van SANS over het scannen van WordPress-plugins wees uit dat meer dan 96% van de kwetsbaarheden in het WordPress-ecosysteem afkomstig is van plugins van derden, met thema's op 4% en de kern op minder dan 1%. Ongeveer 43% van die fouten kan worden misbruikt zonder enige authenticatie. Dus als je audit het grootste deel van zijn energie aan de kern besteedt, bestudeer je de bomen terwijl er in de plugin-map ernaast een bosbrand begint.
Dit is geen oproep om in paniek te raken over de kern. Kernkwetsbaarheden zoals de wp2shell RCE-fouten die recentelijk publieke exploits kregen, moeten op de dag dat ze worden aangekondigd worden gepatcht. Maar ze zijn zeldzaam genoeg dat ze het grootste deel van je audituren niet verdienen. Het grootste deel hoort bij plugins, en daar begint de echte workflow.
Beeld je het scenario van vóór de audit in: op een zondagochtend wordt je site omgeleid naar een casinopagina en je baas mailt: "Ik dacht dat we beveiliging hadden." Je had beveiliging — je had een hokjesoefening. Het scenario na de audit is een triagesysteem dat plugins behandelt als het aanvalsoppervlak dat ze werkelijk zijn, ze van buitenaf test en de dingen controleert die scanners niet kunnen zien.
Je zit in een klein marketingteam met een WordPress-site die sinds 2017 draait. De site heeft een custom eventregistratie-plugin die een freelancer in 2019 heeft gebouwd, een contactformulier-plugin met een bestandsuploadveld, en een slider-plugin die is verkocht en geen openbare updatespagina meer heeft. Dit is geen ongebruikelijke stack. Dit is waar je audit begint.
De plugin-inventaris is je beveiligingsbeleid
Inventariseer elke plugin en elk thema. Noteer de versie, de datum van de laatste update, of de leverancier nog actief is, en of iemand hem daadwerkelijk gebruikt. Classificeer ze daarna in een categorie: onderhouden en gebruikt, onderhouden en ongebruikt, verlaten maar gebruikt, verlaten en ongebruikt. Verwijder de ongebruikte onmiddellijk. Negeer het verweer "het kost maar $50 per maand" — een ongebruikte plugin is een risico, geen functie. Voor de verlaten-maar-gebruikte plugins neem je een besluit: vervangen, of het risico accepteren en het opschrijven in een risicoregister dat je baas heeft gezien.
De eventregistratie-plugin valt in de categorie verlaten maar gebruikt. Hij verwerkt betalingen en verstuurt bevestigingsmails, en het vervangen ervan is een project, dus je houdt hem voorlopig. Maar je schrijft een notitie: "dit is de meest waarschijnlijke bron van een toekomstige inbreuk", en je zet hem bovenaan de testlijst.
| Aanvalsoppervlak | Aandeel van bekende WordPress-kwetsbaarheden | Auditprioriteit |
|---|---|---|
| Plugins van derden | Meer dan 96% | Hoogste — inventariseren, scannen, testen, vervangen |
| Thema's | Ongeveer 4% | Gemiddeld — alleen als ze custom of verouderd zijn |
| WordPress-kern | Minder dan 1% | Laag — gepatcht houden, door gaan |
Toen SecurityWeek in 2024 meer dan 8.000 nieuwe WordPress-kwetsbaarheden telde, was de overgrote meerderheid van dit type: pluginproblemen, geen kernpatches. Een scanner vertelt je over de kwetsbaarheden die zijn gepubliceerd en een CVE hebben gekregen. Hij zal je niets vertellen over de custom code van een freelancer zonder CVE, omdat niemand er ooit zorgvuldig naar heeft gekeken. Die handmatige blik is jouw taak. Voor een diepere uitleg van pluginspecifieke controles, zie deze gids voor het auditen van je WordPress-plugins op kwetsbaarheden.
Test het als een vreemde: de 43% die geen wachtwoord nodig heeft
Je scanner heeft je al verteld dat er niets aan de hand is. Doe nu wat hij niet kan: de site van buitenaf onderzoeken, zonder in te loggen. Begin met elk bestandsuploadveld, elk formulier dat een POST verwerkt, elk admin-ajax-endpoint. Controleert de upload daadwerkelijk de bestandsinhoud, of alleen de extensie? Waar komen de geüploade bestanden terecht, en kan de webserver PHP uitvoeren in die map? De 43% van de pluginfouten die geen authenticatie vereisen, zit meestal precies op deze plekken: niet-geauthenticeerde opgeslagen XSS, willekeurige bestandsupload en PHP-objectinjectie.
De contactformulier-plugin laat bezoekers een cv bijvoegen. Hij hernoemt het bestand met de oorspronkelijke bestandsnaam van de bezoeker, dus je uploadt "resume.php" en hij slaat het op in een /uploads/contact/-map die ontworpen is om beschrijfbaar te zijn. Als de server ook toestaat dat PHP in die map wordt uitgevoerd, heeft de aanvaller meteen een webshell. Fastly heeft actieve exploitatie van niet-geauthenticeerde opgeslagen XSS in WordPress-plugins gedocumenteerd — dit is geen nicherisico voor een presentatie. Je test is eenvoudig: maak een bestand met bekende inhoud, upload het en kijk of het terugkomt met de oorspronkelijke naam en het oorspronkelijke type. Probeer daarna een .php-bestand te uploaden. Als het terugkomt als .php, heb je net een exploiteerbaar gat gevonden.
Dit is ook waar het argument "maar onze beveiligingsplugin heeft een WAF" strandt. Een WAF kan een bekend payload blokkeren, maar de padnormalisatieregels waarop het vertrouwt wijken vaak af van wat de server daadwerkelijk doet. De OWASP Web Security Testing Guide is een betere referentie dan welk dashboard dan ook: het beschrijft hoe je bestandsuploadfouten en opgeslagen XSS op een methodische manier test. En als je ontdekt dat de plugin is verlaten, is het tijd om het opruimprotocol toe te passen: het verborgen gevaar van verlaten WordPress-plugins legt uit waarom het achterlaten van een dode extensie erger is dan het verwijderen en aanpassen van je workflow.
Wat de scanner niet kan zien: gebruikers, logboeken en oude code
Dynamische tests vangen wat op dit moment is blootgesteld. De handmatige controle vangt wat er al binnen is. Begin met gebruikersaccounts: open de beheerderslijst en zoek naar accounts die jij niet hebt aangemaakt. Een beheerder met de naam "support" met een gratis e-mailadres en geen mens erachter is een achterdeur, geen collega. Controleer bestandstijden in wp-content/uploads op alles wat recent is gewijzigd en niet jouw inhoud is. Controleer het servertoegangslogboek op verzoeken die eruitzien als een curl-opdracht van een bot in plaats van de browser van een persoon.
De event-plugin heeft een "sprekerfoto"-upload die opslaat in uploads/event-headshots/. Tijdens de test vind je een bestand dat niet van jou is — een klein PHP-bestand met een willekeurig uitziende naam. Dat is je webshell. Het is daar terechtgekomen via dezelfde uploadfout die je twee weken geleden testte, en tegen die tijd zou een scanner het nog steeds niet "zien" omdat het geen pluginkwetsbaarheid is; het is bewijs van een kwetsbaarheid. De handmatige controle vindt het, verwijdert het en controleert het logboek op het IP-adres dat het daar heeft geplaatst. Invicti heeft opgemerkt dat PHP-objectinjectie in plugins in opkomst is, en het is bijna onzichtbaar voor black-box-scans omdat het kwaadaardige object pas tijdens de uitvoering materialiseert. De enige manier om het te spotten is code lezen op gevaarlijke patronen zoals het aanroepen van unserialize() op gebruikersinvoer. Een paar honderd regels van de custom plugin lezen is goedkoper dan het betalen van een incident-response retainer.
Dit is ook waar het standaardadvies om "gewoon meer beveiligingsplugins te installeren" zijn limiet bereikt. Het stapelen van drie beveiligingsplugins geeft je overlappende WAF-regels die elkaar blokkeren, een stortvloed aan dubbele logmails en af en toe een "je bent gebannen"-fout bij je eigen beheerderslogin. Eén actieve beveiligingsplugin, goed geconfigureerd, is genoeg. Lees over waarom te veel beveiligingsplugins averechts werken voordat je nog iets aan de stapel toevoegt.
Je baas de waarheid vertellen zonder paniek te zaaien
Je baas geeft niets om CVSS-scores of PHP-objectinjectie. Hij geeft om de site die uitvalt, de winkel die geen bestellingen aanneemt en het IT-budget. De vertaling is simpel: "Deze plugin heeft een bekende niet-geauthenticeerde kwetsbaarheid voor externe code-uitvoering. Een vreemde kan de inhoud van onze site verwijderen of een achterdeur installeren. We moeten hem dit kwartaal vervangen." Laat daarna de prioriteitenlijst zien: vervang de event-plugin, schakel de bestandsupload van het contactformulier uit totdat het bestandstypen correct valideert, roteer alle beheerdersreferenties en plan de volgende kwartaalreview.
Je hebt ook een taalvoordeel: CISA onderhoudt de catalogus Known Exploited Vulnerabilities, die je precies vertelt welke gepubliceerde fouten actief in het wild worden misbruikt. Als een van je plugins daarin voorkomt, is het argument niet langer theoretisch — er bestaat een bekende exploit en de klok tikt. Als ze er niet in voorkomen, gebruik de catalogus dan toch als maatstaf voor wat "urgent" betekent. De tracking van CISA maakt het gemakkelijker om een niet-technische baas ervan te overtuigen dat dit geen phishingmail is; het is een openbare database van wat aanvallers op dit moment doen. Wanneer het kwartaal eindigt, heb je een herstelworkflow, geen eenmalige hokjesoefening. Een workflow om kwetsbaarheden om te zetten naar een patchcyclus houdt de gewoonte in stand.
Het scenario van vóór was een kapotte site, een wanhopige e-mail en een schoon scannerrapport dat zei dat er niets aan de hand was. Het scenario na is een kwartaalritueel: inventariseren, classificeren, van buitenaf testen, gebruikers en logboeken controleren, en de beslissingen die je hebt genomen en de risico's die je hebt geaccepteerd opschrijven. De scanner wordt een kaart van waar je moet kijken, geen gezondheidscertificaat. De plugins worden een lijst die je bij naam kent. En de volgende keer dat je baas naar de audit vraagt, heb je een antwoord dat niet inhoudt dat je je vingers kruist.
