Security headers instellen voor je website
Afgelopen week was ik bezig met het migreren van een aantal persoonlijke websites van shared hosting naar Linode. Na het overzetten van alle databases en bestanden stond er nog een klein puntje op mijn actielijst: alle HTTP security headers eens nakijken en (waar mogelijk) goed instellen.
Omdat het niet iets is wat ik dagelijks doe even een samenvatting. For future reference. ;)
Wat zijn HTTP headers?
Als jij een webpagina bezoekt wisselt de server waarop die website gehost informatie met jouw browser. Onder andere over hoe je browser moet omgaan met a) de verbinding naar die website en b) de inhoud van de webpagina. Een aantal van die headers kun je inzetten om je website beter te beveiligen, de zogenaamde security headers.
Om snel te checken hoe jouw website er nu voor staat kun je deze scannen met securityheaders.com. Mijn website begon met een F en scoort nu een A (goed), maar er zijn nog verbeterpunten.
Belangrijke security headers
Er zijn een aantal HTTP security headers beschikbaar om bepaald gebruik van je website te controleren of te beperken. Allemaal gericht op het beperken van risico’s voor bezoekers. Bijvoorbeeld:
- Strict-Transport-Security: hiermee kun je afdwingen dat browsers jouw website alleen via HTTPS inladen. Altijd aanbevolen als je al een SSL-certificaat hebt geinstalleerd.
- X-Frame-Options: om te voorkomen dat je website via een iframe in een andere website wordt ingeladen kun X-Frame-Options instellen. Bijna altijd aan te raden, behalve als je wil toestaan dat inhoud op andere websites 'ingesloten' wordt.
- X-Content-Type-Options: stelt vast dat browsers scripts en stylesheets niet mogen laden als de server niet het correcte MIME type meegeeft. Gericht op het tegengaan van XSS.
- Referrer-Policy: deze bepaalt welke informatie via de HTTP Referer header wordt meegegeven. Je kunt kiezen uit de complete URL van herkomst, alleen de domeinnaam van herkomst, maar je kunt ook kiezen alleen een referrer mee te geven naar andere pagina's binnen je eigen site.
- Permissions-Policy: via browser features en API's kunnen webpagina's toegang vragen tot je camera, microfoon, locatie, etc. Met een Permissions-Policy stel je beperkingen in welke web features je site mag gebruiken. En die gelden dan ook voor embeds!
- Content-Security-Policy: met een CSP stel je heel precies in welke bronnen vanaf welke domeinen mogen worden geladen. En of inline javascript (XSS risico) geladen mag worden. Op de infosec-website van Mozilla vind je meerdere voorbeelden van Content Security Policies.
Security headers instellen
HTTP Security Headers kun je instellen via server-configuratiebestanden, maar ook via plugins/modules van jouw CMS. De eerste optie vond ik het makkelijkst. Zoals altijd: maak even een back-up van de configuratie-bestanden voordat je iets wijzigt.
Op Nginx is dit mijn aanbevolen configuratie (in /etc/nginx/sites-available/sitenaam.conf) :
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
Gebruik je Apache, dan kun je dit toevoegen aan je .htaccess file:
# HTTP security headers
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
In deze aanbevolen configuraties mis je nog Content-Security-Policy, Referrer-Policy en Permissions-Policy. Hiervoor zul je je wel even iets moeten inlezen. De configuratie hiervan hangt af van de opzet van je site. Gebruik je daar 3rd party scripts (analytics) of stylesheets (web fonts)? En hoe belangrijk vind je het dat een referrer wordt meegegeven via kliks vanaf jouw website?
Maar als je voor jezelf die vragen hebt beantwoord ben je klaar. Toch? Nou nee, er zijn alweer nieuwe security headers in aantocht. En ook andere aspecten kun je waarschijnlijk verder aanscherpen (zoals DNSSEC). Met bijvoorbeeld Mozilla’s Observatory en Internet.nl kun je uitgebreider scannen hoe veilig jouw site geconfigureerd is. Bij de eerste scoort roel.io slechts een F 😞, bij de tweede pas 70 van maximaal 100 punten. Werk aan de winkel dus!
Verder lezen?
- Scott Helme, de maker van securityheaders.com, beschrijft hoe zijn bedrijf een pen test liet uitvoeren op een webapplicatie. Goed geconfigureerde security headers waren juist in die situatie waardevol.
- Op het blog van Savvii leggen ze nog eens begrijpelijk in het Nederlands uit wat je met security headers kunt en hoe je deze instelt.
- Mozilla heeft een uitgebreid web security guidelines document.
- Google Developer documentatie over Content-Security-Policy en een CSP-evaluatie-tool