Wie de beveiligingsmeldingen over WordPress-plugins bijhoudt, ziet één term vaker terugkomen dan alle andere. Deze XSS uitleg website gaat over cross-site scripting: de meest gemelde kwetsbaarheid in het WordPress-ecosysteem, en tegelijk de minst begrepen.
Dat komt doordat de schade niet op uw server valt, maar in de browser van uw bezoeker. Uw site draait gewoon door, uw bestanden zijn niet aangepast, en toch loopt er iets mis. Hieronder leest u wat er gebeurt en waarom het ertoe doet.
Wat er precies gebeurt
Uw website stuurt een pagina naar de browser van een bezoeker. Die browser voert alles uit wat er in die pagina staat, inclusief scripts, want zo werkt het web. De browser vertrouwt daarbij alles wat van uw domein komt.
Lukt het een aanvaller om een stukje eigen script in uw pagina te krijgen, dan wordt dat script uitgevoerd alsof het van u komt. Met alle rechten die daarbij horen: het mag bij de cookies van uw site, het mag zien wat de bezoeker invult, en het mag de pagina veranderen.
Er zijn twee vormen die u in de praktijk tegenkomt.
De opgeslagen variant. De code staat in uw database, bijvoorbeeld in een reactie, in een productbeoordeling of in een formulierinzending die in het beheerscherm wordt getoond. Iedereen die die pagina opent, krijgt hem binnen. Dit is de gevaarlijke vorm.
De weerkaatste variant. De code zit in een link. Klikt iemand op een speciaal opgebouwd adres naar uw site, dan geeft uw site die code terug in de pagina. Werkt alleen bij wie op de link klikt, en wordt daarom gecombineerd met phishing.
Wat een aanvaller ermee kan
“Er draait een scriptje mee” klinkt onschuldig. Dit is wat het in de praktijk oplevert:
- De sessie van een ingelogde beheerder overnemen. Het script leest het inlogcookie uit en stuurt het door. De aanvaller zit dan in uw beheerscherm zonder ooit uw wachtwoord te hebben gehad.
- Stilletjes een beheerdersaccount aanmaken op het moment dat u zelf ingelogd bent. Uw browser voert de handeling uit; voor de site lijkt het alsof u het zelf doet.
- Meelezen met wat bezoekers invullen, inclusief betaalgegevens op een afrekenpagina.
- Bezoekers doorsturen naar een andere site, vaak alleen vanaf mobiel of alleen vanuit zoekresultaten, zodat u het zelf niet ziet.
- Een nagemaakt inlogscherm tonen op uw eigen domein. Voor de bezoeker klopt het adres en het slotje, dus er is geen reden tot argwaan.
Dat eerste punt is de reden dat dit ernstiger is dan het lijkt. Cross-site scripting is zelden het doel; het is het opstapje naar volledige toegang. Wat er daarna gebeurt, lijkt op het overnemen van een site met alle zichtbare gevolgen van dien.
Waar het in WordPress vandaan komt
Net als bij andere injectieproblemen zit het vrijwel nooit in de kern van WordPress. Het zit in plugins en thema’s die invoer tonen zonder die eerst onschadelijk te maken. De klassiekers:
- Formulierplugins die inzendingen in het beheerscherm tonen zoals ze binnenkwamen.
- Beoordelings- en reactiefuncties in webshops.
- Instellingenschermen van plugins waar een waarde uit het webadres wordt overgenomen.
- Sliders, tabellen en paginabouwers die eigen HTML toestaan.
- Thema’s met een zoekfunctie die de ingetikte zoekterm ongefilterd terug op de pagina zet.
Opvallend detail: veel van deze kwetsbaarheden zijn alleen te misbruiken door iemand die al is ingelogd, bijvoorbeeld als abonnee of als klant. Dat maakt ze minder ernstig, maar niet ongevaarlijk, zeker op een site waar bezoekers zelf een account kunnen aanmaken.
Wat u eraan doet
Bijwerken. Dit blijft de belangrijkste maatregel, en bij deze categorie helemaal, omdat de fout in de code van een plugin zit en alleen de maker hem kan repareren.
Beperk wie er mag inloggen. Staat registratie open terwijl u dat niet gebruikt, zet het dan uit. Dat is één vinkje onder de algemene instellingen en het haalt een hele categorie aanvallen weg.
Geef niet iedereen beheerdersrechten. Hoe minder accounts met volledige rechten, hoe kleiner de kans dat een overgenomen sessie schade oplevert.
Modereer reacties. Wie reacties direct laat verschijnen zonder controle, laat feitelijk vreemden meeschrijven aan zijn pagina’s. Zet goedkeuring vooraf aan, of schakel reacties uit als u ze niet gebruikt.
Zet beveiligingsheaders aan. Een goed ingesteld beleid voor welke scripts er mogen draaien, beperkt de schade van een script dat er tóch in komt. Achtergrond staat in het artikel over beveiligingsheaders zoals HSTS en CSP.
Log uit als u klaar bent. Klinkt ouderwets, maar een groot deel van deze aanvallen werkt alleen als er een ingelogde beheerder langskomt.
Hoe u het opmerkt
Vaak pas via de gevolgen: klanten die melden dat ze op een vreemde site belanden, een zoekmachine die uw pagina’s als onveilig markeert, of een beheerdersaccount dat er ineens bij staat. Rechtstreeks kijken kan ook: open een pagina met veel gebruikersinvoer, bekijk de broncode en let op scripttags die er niet horen.
Vindt u iets, dan is opruimen alleen niet genoeg. De invoer die het veroorzaakt staat in uw database en komt terug zodra de pagina opnieuw wordt getoond. U moet dus én de plugin bijwerken, én de besmette inzending verwijderen.
Dit soort meldingen volgen en beoordelen of ze op úw site van toepassing zijn, is werk dat zich slecht leent voor incidenteel doen. Het is een vast onderdeel van het bijhouden van kwetsbaarheden en updates voor een WordPress-site, en bij WebMaintor is dat de reden dat we de pluginlijst per klant vastleggen: dan is bij een nieuwe melding binnen een minuut duidelijk wie het betreft.
Concrete volgende stap: kijk onder de algemene instellingen of registratie voor bezoekers openstaat terwijl u dat niet gebruikt. Dat vinkje uitzetten kost tien seconden en sluit een flink deel van deze aanvallen uit.



