Kennisbank

Cross-site scripting (XSS): hoe een reactieformulier een aanvalswapen wordt

Bijgewerkt: 5 september 2026 · 6 min leestijd

Stel je voor: je bezoekt een webwinkel en leest de klantbeoordelingen bij een product. Alles ziet er normaal uit, maar op de achtergrond stuurt jouw browser, zonder dat je het merkt, je inlogcookie naar een onbekende server. Dat gebeurde niet omdat de webwinkel gehackt is in de klassieke zin, maar omdat iemand ergens een stukje code had verstopt in precies zo'n klantbeoordeling. Dat is in de kern cross-site scripting, meestal afgekort tot XSS: een aanvaller laat kwaadaardige code meeliften op een website die jij vertrouwt, waardoor jouw browser die code net zo behandelt als de rest van de pagina.

De naam klinkt technisch, maar de analogie is simpel. Denk aan een gastenboek op een website waarin bezoekers een bericht kunnen achterlaten dat later gewoon op de pagina verschijnt. Normaal typ je daar tekst. Maar als de site niet goed controleert wat je invoert, kun je in plaats van tekst een klein 'commando' voor de browser van andere bezoekers achterlaten. Iedereen die het gastenboek daarna bekijkt, voert dat commando dan onbewust uit, gewoon omdat het van de vertrouwde website lijkt te komen. XSS misbruikt dus niet zozeer een server, maar het vertrouwen dat jouw browser heeft in de site die je bezoekt.

Wat is het precies?

Websites bestaan grotendeels uit HTML (de opmaaktaal voor pagina's) en JavaScript, de programmeertaal die in je browser draait en pagina's interactief maakt: knoppen die reageren, formulieren die valideren, animaties, noem maar op. Browsers zijn ontworpen om JavaScript dat bij een pagina hoort, gewoon uit te voeren.

Het probleem ontstaat wanneer een website invoer van gebruikers, zoals een reactie, zoekterm of profielnaam, ongefilterd teruglaat zien aan andere bezoekers. Als een aanvaller in plaats van gewone tekst een stukje JavaScript invoert, bijvoorbeeld verstopt tussen HTML-tags, en de site dat zonder opschoning ('sanitizing' of 'escaping', het onschadelijk maken van speciale tekens) publiceert, voert de browser van elke bezoeker dat script uit alsof het bij de site hoort.

Vakmensen onderscheiden meestal drie varianten. Bij opgeslagen (stored) XSS blijft de kwaadaardige code permanent op de server staan, bijvoorbeeld in een database met reacties, en treft die iedereen die de pagina bezoekt. Bij reflected XSS zit de schadelijke code in een link of zoekopdracht en verschijnt hij alleen in het antwoord van de server aan wie op die specifieke link klikt; aanvallers verspreiden zulke links vaak via e-mail of social media. De derde variant, DOM-gebaseerde XSS, speelt zich volledig af in de browser zelf: JavaScript op de pagina verwerkt onveilig gebruikersinvoer (bijvoorbeeld uit de URL) zonder dat de server daar iets van merkt.

Wat het script vervolgens doet, is aan de aanvaller. Populaire doelen zijn het stelen van sessiecookies (waarmee iemand kan inloggen als jou), het aftappen van wachtwoorden uit formulieren, het omleiden naar nepsites, of het automatisch uitvoeren van acties namens het slachtoffer, zoals berichten versturen of instellingen wijzigen.

Wat wil men ermee bereiken?

Vanuit het perspectief van een aanvaller is het doel meestal identiteitsdiefstal of controle: toegang krijgen tot een account, gevoelige gegevens buitmaken, of een aanval verder verspreiden. Omdat het script draait mét de rechten van de bezochte website, kan het dingen doen die een aanvaller normaal nooit voor elkaar zou krijgen, zoals gegevens uit een beveiligde sessie lezen.

Vanuit het perspectief van de beveiligingswereld bestaat er juist een heel veld rond het voorkomen van dit soort aanvallen. Browserbouwers, standaardisatie-organisaties en ontwikkelaars van websoftware willen drie dingen bereiken: gebruikersinvoer altijd als 'onvertrouwd' behandelen totdat het bewezen veilig is, browsers technische grenzen laten afdwingen tussen code van de site en code van een aanvaller, en ontwikkelaars tools geven waarmee fouten vanzelf worden voorkomen in plaats van pas achteraf ontdekt. Dat laatste is precies waarom moderne webframeworks (zoals React of Angular) tekst standaard 'escapen', dus onschadelijk maken, tenzij een ontwikkelaar expliciet aangeeft dat ruwe HTML gewenst is.

Voorbeelden uit de praktijk

Het bekendste voorbeeld is de Samy-worm op MySpace in 2005. Een achttienjarige gebruiker genaamd Samy Kamkar plaatste een stukje JavaScript in zijn profiel dat, wanneer iemand zijn pagina bekeek, zichzelf kopieerde naar het profiel van die bezoeker én Samy automatisch als vriend toevoegde. Binnen ongeveer twintig uur had meer dan een miljoen profielen de code opgepikt, wat MySpace dwong de site tijdelijk offline te halen.

In september 2010 trof een vergelijkbare kwetsbaarheid Twitter. Door een fout in de manier waarop tweets werden weergegeven, konden aanvallers code laten uitvoeren zodra iemand met zijn muis over een link bewoog (de zogeheten 'onMouseOver-worm'). Duizenden accounts, waaronder die van bekende gebruikers, verstuurden daardoor ongewild besmette tweets.

In juni 2014 werd TweetDeck, een beheertool van Twitter voor het volgen van meerdere accounts, getroffen door een vergelijkbare opgeslagen XSS-kwetsbaarheid: een tweet met kwaadaardige code opende bij weergave automatisch pop-ups en retweette zichzelf, waardoor de tool tijdelijk uit de lucht werd gehaald.

Een recenter voorbeeld komt van beveiligingsonderzoekers van Check Point Research, die in januari 2019 een kwetsbaarheid in de inlogomgeving van Fortnite (ontwikkelaar Epic Games) rapporteerden. Door een XSS-fout te combineren met een zwakte in het inlogproces konden onderzoekers, in theorie, accounts overnemen en gesprekken en betaalgegevens van spelers inzien. Epic Games verhielp het probleem nadat het verantwoord was gemeld.

Ook grote platformen als eBay kregen door de jaren heen herhaaldelijk te maken met gemelde stored-XSS-problemen in productadvertenties, wat illustreert dat het probleem niet is voorbehouden aan kleine of onervaren partijen.

Hoe ver is de techniek?

XSS is geen nieuw fenomeen: het wordt al sinds begin jaren 2000 als aparte categorie kwetsbaarheden erkend en staat al meer dan twee decennia vrijwel onafgebroken in de invloedrijke OWASP Top 10, een door de non-profitorganisatie OWASP samengestelde lijst van de belangrijkste webbeveiligingsrisico's. Dat het nog steeds op die lijst staat, laat zien dat het probleem niet is 'opgelost', ook al is er veel vooruitgang geboekt.

Twee ontwikkelingen hebben de situatie de afgelopen jaren merkbaar verbeterd. Ten eerste passen moderne frontend-frameworks zoals React, Vue en Angular van huis uit automatische 'escaping' toe, waardoor veel klassieke fouten er simpelweg niet meer in sluipen tenzij een ontwikkelaar bewust een onveilige functie gebruikt. Ten tweede kunnen websites een Content Security Policy (CSP) instellen, een instructie aan de browser over welke scriptbronnen wel en niet mogen draaien, wat de schade van een geslaagde injectie sterk kan beperken. Chrome experimenteert bovendien met een nieuwere API genaamd Trusted Types, die dwingt dat onveilige HTML expliciet als veilig wordt gemarkeerd voordat de browser die uitvoert.

Toch blijft het een kat-en-muisspel. Verouderde bedrijfssoftware, maatwerkapplicaties en snel gebouwde functies zonder beveiligingsreview blijven kwetsbaar, en onderzoekers en bug bounty-platformen zoals HackerOne rapporteren nog altijd op grote schaal nieuwe XSS-bevindingen. Chrome heeft in 2019 zelfs zijn ingebouwde 'XSS Auditor', een filter dat bepaalde patronen probeerde te blokkeren, uitgeschakeld omdat die onvoldoende effectief bleek en soms zelfs nieuwe problemen veroorzaakte; de nadruk ligt sindsdien vooral op preventie aan de kant van ontwikkelaars in plaats van filtering aan de kant van de browser.

Wie werken eraan?

OWASP (Open Worldwide Application Security Project) speelt een centrale rol als non-profitgemeenschap die documentatie, testrichtlijnen en de genoemde Top 10 opstelt, gebruikt door beveiligingsteams wereldwijd. Browserbouwers als Google (Chrome), Mozilla (Firefox) en Microsoft (Edge) ontwikkelen gezamenlijk, vaak via het World Wide Web Consortium (W3C), standaarden zoals Content Security Policy en Trusted Types.

Daarnaast dragen makers van webframeworks, waaronder de teams achter React (Meta) en Angular (Google), actief bij door veilige standaardinstellingen in hun software in te bouwen. Onafhankelijke onderzoeksgroepen en trainingsplatformen zoals PortSwigger, bekend van de Burp Suite-beveiligingstools en de gratis Web Security Academy, leveren veel praktijkgericht onderzoek en educatie. Ook overheidsinstanties zoals het Amerikaanse NIST en nationale computer emergency response teams (CERT's), waaronder het Nederlandse NCSC, publiceren richtlijnen voor organisaties om XSS-risico's te beperken. Ten slotte spelen bug bounty-platformen als HackerOne en Bugcrowd een grote rol: zij verbinden bedrijven met onafhankelijke onderzoekers die tegen een beloning kwetsbaarheden, waaronder veel XSS-gevallen, verantwoord melden voordat kwaadwillenden ze kunnen misbruiken.

Verder lezen