Webbeveiliging

Content Security Policy (CSP)

Definitie

De Content Security Policy (CSP) is een HTTP-header waarmee een site de browser vertelt uit welke bronnen hij scripts, stylesheets, afbeeldingen of frames mag laden. Alles wat niet op die lijst staat, wordt geblokkeerd, wat de impact van een XSS-lek sterk beperkt.

Content Security Policy (CSP), Webbeveiliging

In de praktijk is de CSP een allowlist die de server met elke pagina meestuurt. De browser leest hem voordat hij iets uitvoert en weigert alles wat er niet op staat: een script van een onbekend domein, een geïnjecteerde stijl, een frame of formulier dat naar elders wijst. Het grootste voordeel is dat hij de schade van een XSS-lek beperkt: ook als een aanvaller code in een pagina weet te krijgen, kan de browser weigeren die uit te voeren.

Hoe een Content Security Policy werkt

Een beleid bestaat uit directives, gescheiden door puntkomma's. Elke directive geldt voor een type bron en somt de toegestane bronnen op:

  • default-src is de standaardwaarde voor alle bronnen zonder eigen directive;
  • script-src, style-src, img-src, font-src gelden voor scripts, stylesheets, afbeeldingen en lettertypen;
  • frame-ancestors bepaalt welke sites de pagina in een frame mogen tonen, wat beschermt tegen clickjacking;
  • object-src 'none', base-uri en form-action sluiten minder bekende injectieroutes af.

Zodra er een directive script-src of default-src bestaat, worden scripts die direct in de HTML staan en attributen als onclick geblokkeerd. Het sleutelwoord 'unsafe-inline' heft dat verbod op, maar MDN wijst erop dat het een groot deel van het nut van de CSP tenietdoet. De aanbevolen methode, strict CSP genoemd, staat scripts toe via een nonce (een willekeurige waarde die bij elk antwoord anders is en in de <script>-tag wordt herhaald) of via de SHA-256-hash van het script.

Schema in vijf stappen: de server stuurt de pagina met een Content-Security-Policy-header, een geïnjecteerd script van een kwaadaardig domein staat in de pagina, de browser vergelijkt de herkomst en de nonce met het beleid, weigert het uit te voeren en kan een overtredingsrapport naar de site sturen
De browser past het beleid toe: een script waarvan de herkomst of de nonce niet klopt, wordt niet uitgevoerd.

Header, meta-tag en report-only-modus

Het beleid verstuur je bij voorkeur in de HTTP-header Content-Security-Policy. Een tag <meta http-equiv> werkt ook, maar de W3C-specificatie zegt dat die frame-ancestors, sandbox en report-uri negeert en geen beleid in report-only-modus kan bevatten.

Die report-only-modus is de sleutel tot een invoering zonder schade. Met Content-Security-Policy-Report-Only verbiedt de browser niets: hij meldt alleen, in de console of naar een adres dat je opgeeft met report-to en de header Reporting-Endpoints, wat hij zou hebben geblokkeerd. Je past de lijst aan en schakelt daarna over op de blokkerende modus.

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'nonce-r4nd0m'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'
Video: “Content Security Policy explained | how to protect against Cross Site Scripting (XSS)” (Jan Goebel, in het Engels)

Voor WordPress

WordPress is lastig terrein voor een strict CSP: de core, thema's en veel plugins zetten inline scripts in de pagina. Sinds WordPress 5.7 kun je met de functies wp_get_inline_script_tag(), wp_print_inline_script_tag() en de filter wp_script_attributes een nonce-attribuut toevoegen aan scripts die netjes worden geladen, maar niet aan scripts die een thema hard in de code heeft staan. Daarom beginnen veel sites met 'unsafe-inline' en verscherpen ze het beleid pagina voor pagina.

  • Test in report-only-modus de homepage, een bericht, de blokeditor, de formulieren en de betaling.
  • Zet het beleid op serverniveau (.htaccess, Nginx) als een cache pagina's serveert zonder langs PHP te gaan.
  • Inventariseer de externe domeinen: lettertypen, statistieken, video's, betaalprovider.

Onze gids over beveiligingsheaders voor WordPress geeft een startbeleid en de testmethode, en het artikel over XSS-lekken in WordPress laat zien wat een CSP had kunnen beperken. De CSP hoort bij een bredere familie van HTTP-beveiligingsheaders.

Veelgemaakte fouten

  • Een strikt beleid uit een tutorial kopiëren en direct toepassen: de editor of de winkelwagen werkt dan niet meer.
  • Dezelfde nonce op meerdere pagina's hergebruiken: hij moet onvoorspelbaar zijn en bij elk antwoord veranderen, wat slecht samengaat met een paginacache.
  • Denken dat de CSP het escapen van gegevens vervangt: OWASP ziet hem als defense in depth, niet als de enige bescherming tegen XSS.

WP Masquerade Pro biedt een basis-CSP die browserplugins blokkeert, het base-adres beschermt en bronnen naar HTTPS omzet. Die beperkt bewust geen scripts: een beleid tegen XSS moet je op maat bouwen, in de configuratie van de server of het CDN.

Verder lezen

  • Artikel Zo stel je HTTP-beveiligingsheaders in op WordPress: CSP, HSTS en de rest
  • Pagina Beveiligingsheaders voor WordPress

Bronnen

  1. MDN: Content Security Policy (CSP) (externe link, opent in een nieuw tabblad)
  2. W3C: Content Security Policy Level 3 (externe link, opent in een nieuw tabblad)
  3. OWASP: Content Security Policy Cheat Sheet (externe link, opent in een nieuw tabblad)
  4. Make WordPress Core: fonctions d’attributs de scripts dans WordPress 5.7 (externe link, opent in een nieuw tabblad)

Alle definities

WordPress-beveiliging, zonder ruis

Eén e-mail wanneer het ertoe doet: nieuw waargenomen aanvallen, updates van de plugin en praktische gidsen. Geen spam, afmelden met één klik.

Begin gratis, stap over op Pro wanneer je eraan toe bent

De gratis versie verbergt WordPress al en verplaatst de inlogpagina. Pro voegt aliassen, tweestapsverificatie en bewaking toe.