Content Security Policy (CSP)
Je website staat open voor de wereld — en helaas ook voor aanvallers. Een van de meest voorkomende aanvallen op websites is Cross-Site Scripting (XSS): een aanvaller slaagt erin om kwaadaardige JavaScript te laten uitvoeren in de browser van jouw bezoeker. Met een Content Security Policy (CSP) geef je de browser een whitelist mee: alleen code en middelen van goedgekeurde bronnen mogen worden geladen.
Hoe werkt een CSP?
Een CSP is een HTTP-header die de server meestuurt met elke pagina. De browser leest de header en weigert alles te laden dat niet expliciet is toegestaan.
Stel je hebt een pagina die een script van een onbekende externe bron probeert te laden:
<!-- Dit wordt geblokkeerd als de CSP externe scripts niet toestaat -->
<script src="https://kwaadaardige-site.ru/hack.js"></script>
Met een goede CSP ziet de bezoeker niets van de aanval — de browser weigert het script gewoon te laden.
De HTTP-header instellen
De aanbevolen manier is via een HTTP-header op je server. Hoe je dat configureert, hangt af van de server die je gebruikt.
Nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self';";
Express.js (Node.js)
app.use((req, res, next) => {
res.setHeader(
'Content-Security-Policy',
"default-src 'self'; script-src 'self'; style-src 'self';"
)
next()
})
Gebruik je Express.js? Het pakket Helmet stelt automatisch een verzameling veiligheidsheaders in, waaronder een CSP. Dit is de aanbevolen aanpak voor Node.js applicaties.
Via een meta-tag (alternatief)
Als je geen controle hebt over de serverinstellingen, kun je een beperkte CSP instellen via een <meta> tag in de <head> van je HTML. Let op: niet alle CSP-directives werken via een meta-tag.
<head>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self';"
/>
</head>
De belangrijkste directives uitgelegd
Een CSP-waarde bestaat uit meerdere directives, gescheiden door puntkomma's. Elk directive bepaalt welk type resource van welke bron geladen mag worden.
| Directive | Wat het regelt |
|---|---|
default-src | Vangnet voor alles wat niet door een specifieker directive gedekt wordt |
script-src | JavaScript bestanden en inline scripts |
style-src | CSS bestanden en inline stijlen |
img-src | Afbeeldingen |
font-src | Lettertypes (bijv. Google Fonts) |
connect-src | API-verzoeken via fetch, XMLHttpRequest, WebSockets |
frame-src | Ingesloten <iframe> inhoud |
Veelgebruikte bronwaarden
| Waarde | Betekenis |
|---|---|
'self' | Alleen van dezelfde domeinnaam als de huidige pagina |
'none' | Helemaal niets toestaan |
https://cdn.example.com | Alleen van dit specifieke domein |
https: | Van elke HTTPS-bron |
'unsafe-inline' | Inline code toestaan — gebruik dit zo min mogelijk |
Een praktisch voorbeeld
Hier is een realistische CSP voor een website die Google Fonts en een externe analytics-dienst gebruikt:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://plausible.io;
style-src 'self' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
img-src 'self' data:;
connect-src 'self' https://plausible.io;
Wat dit beleid inhoudt:
- Scripts: alleen van de eigen server en Plausible Analytics
- Stijlen: eigen server en Google Fonts CSS
- Lettertypes: eigen server en Google Fonts bestanden
- Afbeeldingen: eigen server én inline base64-afbeeldingen (
data:) - API-verzoeken: eigen server en Plausible Analytics
CSP testen zonder te blokkeren
Ben je bang dat een te strenge CSP iets breekt? Gebruik dan Content-Security-Policy-Report-Only. De browser past de policy niet toe, maar logt wel alle overtredingen naar de console — perfect om te testen.
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self';
Begin met een strenge policy (default-src 'none') en voeg directives toe totdat alles werkt. Het is veel makkelijker te versoepelen dan achteraf te verstrengen. Open de DevTools Console — elke CSP-overtreding verschijnt daar als foutmelding met exacte uitleg.
Een goed geconfigureerde CSP is een van de krachtigste beveiligingsmaatregelen die je als webdeveloper kunt nemen — en het kost maar een paar regels configuratie.