
23 augustus 2022 · 7 min read
We ontvangen steeds vaker vragen van onze klanten over het (veilig) configureren van een Content Security Policy (CSP). Daarom hebben we besloten om onze kennis over het instellen van een CSP te delen via deze blogpost. De CSP geeft de browser instructies over vanaf welke locatie welke resources ingeladen mogen worden. Daarnaast geeft het instructies hoe deze binnen de applicatie gebruikt mogen worden. Een goed ingestelde CSP kan fijnmazige instructies bevatten over wat er wel en niet uitgevoerd mag worden en kan daardoor kwetsbaarheden zoals Cross-Site Scripting (XSS) afvangen en voorkomen.
De CSP-standaard heette oorspronkelijk Content Restrictions en was in 2004 door Robert Hansen (Mozilla) in het leven geroepen. Deze aankondiging werd op de website ha.ckres.org gedaan en is via de Wayback Machine terug te vinden. De header werd als eerst ondersteund door Mozilla Firefox 4 en andere browsers volgden al snel. In 2012 werd de CSP als W3C-kanditaat aanbevolen en dit bevorderde de adoptie van deze security header. Later volgden level 2 (2014) en level 3 (2015) van de CSP en deze worden op dit moment door de meeste webbrowsers ondersteund.
De CSP-header heeft in het verleden meerdere alternatieven en implementaties gekend. De volgende headernamen zijn bij voorgaande implementaties gebruikt:
De huidige CSP implementatie bestaat uit de header Content-Security-Policy gevolgd door applicatieafhankelijke waarden en attributen. Een applicatie kan bijvoorbeeld de onderstaande CSP-header meesturen:
default-src 'self'; object-src 'none'; child-src 'self'; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content
Het belangrijkste voordeel van een CSP is het voorkomen van Clickjacking en injectie-kwetsbaarheden zoals Cross-Site Scripting (XSS). Met een strak afgestelde CSP kan een kwaadwillende die een XSS-kwetsbaarheid vindt, deze niet uitbuiten omdat de webbrowser van het slachtoffer de uitvoer van scriptcode blokkeert.
Daarnaast wordt een (strak afgestelde) CSP steeds vaker een verplichting vanuit audits. Tijdens een DigiD pentest wordt bijvoorbeeld gecontroleerd of binnen de CSP geen onveilige functies zoals unsafe-eval en unsafe-inline gebruikt worden.
Het instellen van een strak afgestelde CSP is applicatieafhankelijk, er bestaat geen one-site-fits-all CSP. Een CSP is opgebouwd uit meerdere attributen en waarden en deze verschillen per applicatie. Onderstaand volgt er per attribuut een korte beschrijving over welke instructies en gedragingen het de webbrowser kan opleggen:
De CSP-header kan op meerdere plaatsen gezet worden. Eén van de plaatsen waar de CSP gezet kan worden is in de HTML met een meta-tag. Onderstaand wordt hier een voorbeeld van gegeven. Let op dat dit een voorbeeld is en niet zomaar overgenomen kan worden:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; img-src https://phishify.nl/; child-src 'hackify.nl';">
Om een CSP binnen Apache2 te definiëren is de eerste vereiste het installeren van de module: a2enmod headers. Deze module kan via onderstaande commando’s geïnstalleerd en geactiveerd worden:
root@pentests:/etc/apache2# a2enmod headers
Enabling module headers.
To activate the new configuration, you need to run:
systemctl restart apache2
root@pentests:/etc/apache2# systemctl restart apache2
root@pentests:/etc/apache2#
Na dit geïnstalleerd te hebben kan de CSP vrij makkelijk met een htaccess-bestand worden toegevoegd. Er dient een regel te worden toegevoegd die voorafgaat met “Header add Content-Security-Policy” gevolgd door de gewenste CSP-waarden. Onderstaand geven we een voorbeeld:
Header add Content-Security-Policy " default-src 'self'; img-src https://phishify.nl/; child-src 'hackify.nl';
Voor meer informatie over het zetten van een CSP binnen Apache verwijzen we naar de volgende URL: https://content-security-policy.com/examples/htaccess/
Binnen Nginx kan de CSP-header worden ingesteld binnen het configuratiebestand van de webserver, specifiek in de sectie server{}.Onderstaand volgt een voorbeeld hoe de CSP gezet kan worden:
"server"{
listen 443;
server_name pentests.nl;
add_header Content-Security-Policy"default-src 'self';""always; location /"{
}
}
Let op dat je na elke wijziging de Nginx moet herstarten zodat de wijzingen doorgevoerd worden. Nginx kan met onderstaande commando herstart worden:
nginx -s reload
Voor meer informatie over hoe een CSP ingesteld kan worden binnen Nginx verwijzen we naar deze webpagina.
Binnen een Internet Information Services (IIS) webserver kan een CSP ingesteld worden door de IIS Manager te openen en de header toe te voegen aan de HTTP Response Headers.

Door op de knop “Toevoegen” te klikken kan de CSP-header inclusief de juiste waarden ingevuld worden:

Het instellen van een strikte CSP kan een uitdaging zijn. Vaak is een applicatie al gebouwd en wordt er pas achteraf gedacht aan het configureren van een CSP. Gelukkig zijn er websites en extensies die het opstellen van een CSP automatiseren. Het automatisch genereren van een CSP biedt echter geen garantie dat de CSP-configuratie volledig veilig is. Wel helpt het om snel en makkelijk een beeld te krijgen hoe de CSP er ongeveer uit komt te zien.
In het onderstaande voorbeeld maken we gebruik van de browserextensie voor Google Chrome van csper.io.

Nadat er op “Start Building Policy” geklikt is moet er handmatig door de applicatie genavigeerd worden. Om de gegenereerde CSP zo volledig mogelijk te genereren is het van belang dat de extensie zo veel mogelijk webpagina’s bezoekt. In het voorbeeld van pentests.nl leidt dit tot een totaal van 740 reports.

Door op “Next” te klikken wordt er vervolgens inzicht gegeven in op welke plekken er inline scriptcode zoals JavaScript staat. Het wordt aangeraden om deze scriptcode onder te brengen in een separaat bestand of deze te voorzien van een nonce. Tenslotte wordt in de vierde stap de gegenereerde CSP gegeven. Deze kan (met eventuele kleine aanpassingen) worden overgenomen. Het wordt aangeraden om de CSP eerst in report-only mode te zetten. In onderstaande alinea wordt hier meer uitleg over gegeven.
Het configureren van een CSP kent vele uitdagingen en valkuilen. Daardoor bestaat een kans dat het ook legitieme bronnen en/of functionaliteiten van de applicatie blokkeert. Dit heeft een negatieve invloed op het functioneren van de applicatie en het gebruiksgemak van de eindgebruikers. De makers van de CSP hebben het daarom mogelijk gemaakt om de CSP eerst in report-only te gebruiken. Hierbij wordt de CSP inclusief alle attributen en waarden gezet, maar hoeft de webbrowser van de eindgebruiker er geen gehoor aan te geven. Wel worden eventuele CSP-overtredingen gerapporteerd. Dit geeft ontwikkelaars inzicht in mogelijk verkeerd gedefinieerde CSP-waarden. Onderstaand wordt een voorbeeld gegeven hoe deze functie gebruikt kan worden:
Content-Security-Policy-Report-Only: <CSP-attribuut>: <waarde>; <CSP-attribuut>
Het instellen van een strikte Content Security Policy (CSP) biedt een extra beveiligingslaag en kan (mits goed afgesteld) injectie-kwetsbaarheden zoals XSS voorkomen. Het beveiligen van een webapplicatie met een CSP kan echter een uitdaging vormen.
Heeft u vragen over het instellen van een CSP of andere beveiligingsvragen rondom uw webapplicatie? Misschien is een webapplicatie pentest iets voor u? Daarnaast kunt u vrijblijvend contact met ons opnemen, we helpen u graag verder.