Securityheaders: waarom je website waarschijnlijk de meest basale securitycontrole niet haalt

Vijf HTTP-responseheaders. Bij de meeste websites ontbreken er minstens drie. Wat ze doen, waarom aanvallers op de gaten letten en hoe je het in één middag oplost.

Als je browser een website laadt, stuurt de server meer terug dan alleen de HTML. Er gaan ook een set HTTP-responseheaders mee: kleine instructies die de browser vertellen hoe hij zich moet gedragen. Het grootste deel is technische regelgeving waar niemand naar omkijkt. Maar vijf ervan zijn securitycontroles, en als ze ontbreken of verkeerd zijn ingesteld, heeft de browser geen enkele manier om je bezoekers te beschermen tegen een hele klasse aan aanvallen.

We draaien deze check op elke site in Noroshi. In onze dataset van Europese mkb-websites faalt meer dan 80% op minstens drie van deze vijf headers. Het goede nieuws: oplossen kost niets en kan binnen een middag.

Wat securityheaders echt doen

Securityheaders zijn de manier waarop de server de grondregels voor de browser vastlegt. Zonder die headers valt de browser terug op zijn meest toegeeflijke defaults: hij voert elk script uit, toont de pagina in het frame van elke andere pagina, verstuurt cookies over HTTP en deelt je servertype met iedereen die ernaar vraagt. Elk van die defaults is talloze keren misbruikt.

De vijf headers die er het meest toe doen:

1. Content-Security-Policy (CSP)

CSP vertelt de browser welke scripts, stylesheets, fonts en andere bronnen mogen laden. Een strikte CSP stopt geïnjecteerde scripts direct: zelfs als een aanvaller erin slaagt een script-tag in je HTML te plaatsen (via een kwetsbaarheid in je CMS of een gecompromitteerde third-party library), weigert de browser het script gewoon uit te voeren.

Zonder CSP is je site kwetsbaar voor cross-site scripting (XSS). XSS staat structureel in de OWASP Top 10 van meest kritieke webapplicatierisico's en is de aanval achter de meeste checkout-manipulatie: een script dat in je betaalpagina wordt geïnjecteerd stuurt kaartnummers naar de server van de aanvaller terwijl de transactie voor alle betrokkenen normaal oogt.

Een strikt startbeleid voor een site die alleen zijn eigen bronnen laadt: Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'. Gebruik je externe fonts, analytics of een betaalwidget, dan moeten die origins expliciet worden genoemd.

2. Strict-Transport-Security (HSTS)

HSTS vertelt browsers dat ze je domein altijd via HTTPS moeten benaderen, voor een bepaalde periode, en dat ze elke HTTP-verbinding moeten weigeren, inclusief redirects. Zonder HSTS kan een aanvaller op hetzelfde netwerk (een openbaar wifi-netwerk, een gecompromitteerde router) het eerste verzoek onderscheppen en de verbinding terugbrengen naar plain HTTP vóórdat de redirect plaatsvindt.

De header ziet er zo uit: Strict-Transport-Security: max-age=31536000; includeSubDomains. De max-age is een jaar, het minimum dat Google aanraadt voor HSTS preload-geschiktheid. Voeg preload toe aan de directive en meld je domein aan voor de browser-preloadlist om gebruikers ook bij hun allereerste bezoek te beschermen.

3. X-Frame-Options

Deze header voorkomt dat je pagina in een <iframe> op een andere site wordt ingesloten. Zonder die header kan een aanvaller je inlogpagina onzichtbaar in zijn eigen pagina laden en er nep-UI-elementen bovenop leggen. De gebruiker denkt dat hij op jouw knop klikt, maar klikt op die van de aanvaller. Dit heet clickjacking.

De oplossing is één regel: X-Frame-Options: DENY (of SAMEORIGIN als je eigen pagina's insluit). De CSP-directive frame-ancestors is de moderne tegenhanger en gaat vóór X-Frame-Options als beide aanwezig zijn.

4. X-Content-Type-Options

Browsers proberen behulpzaam te zijn door het type van een bron te raden als de server het niet duidelijk declareert. Dit heet MIME sniffing en het is een beveiligingsprobleem: een geüploade afbeelding die in werkelijkheid een script is, kan worden uitgevoerd als de browser besluit dat het op JavaScript lijkt.

X-Content-Type-Options: nosniff zet dit gokgedrag volledig uit. Het is de makkelijkste header uit deze lijst: één regel, geen configuratie, geen bijwerkingen.

5. Referrer-Policy

Als een gebruiker op een link van jouw site naar een andere site klikt, stuurt de browser een Referer-header met de URL van de pagina waar hij vandaan kwam. Bevatten je URLs gevoelige gegevens (een wachtwoord-resettoken, een sessie-ID, een orderreferentie), dan lekken die gegevens naar de doelsite.

Referrer-Policy: strict-origin-when-cross-origin is de veilige default: naar externe sites gaat alleen de origin (je domeinnaam, zonder pad) en naar je eigen domein de volledige URL. De meest privacyvriendelijke optie is no-referrer, maar die breekt sommige analytics-integraties.

Hoe je je site controleert

Het snelst is: open de developer tools van je browser (F12), laad je homepage, ga naar het tabblad Network, klik op het eerste verzoek en bekijk het onderdeel Response Headers. Of gebruik Noroshi: maak een gratis account, voeg je domein toe en de scanner controleert alle vijf de headers, geeft er een score aan en legt exact uit wat je waar moet toevoegen.

Waar je ze instelt

Securityheaders worden op de webserver ingesteld, niet in je CMS. Waar precies hangt af van je hostingopzet:

  • Apache: in je .htaccess-bestand of httpd.conf met Header always set-directives. De module mod_headers moet aan staan.
  • Nginx: in je serverblock met add_header-directives. Zet ze in het server- of location-block dat jouw site afhandelt.
  • Caddy: in je Caddyfile met de header-directive. Caddy zet X-Content-Type-Options: nosniff automatisch; de rest moet je zelf toevoegen.
  • Cloudflare of een andere proxy: sommige proxies laten je responseheaders toevoegen via hun dashboard (Cloudflare: Transform Rules, Modify Response Header). Dat is de makkelijkste optie als je de serverconfiguratie niet kunt aanpassen.
  • WordPress: plugins als Wordfence, Headers Security Advanced en HSTS Preload zetten headers zonder servertoegang. Dat is een redelijke uitwijkmogelijkheid als je hostingprovider de serverconfiguratie beheert.

Wat je van je score kunt verwachten

Het toevoegen van alle vijf de headers brengt een Noroshi-securityscore doorgaans in één sessie van de 40-60 naar de 70-80. Ze zijn niet het enige dat telt (TLS-configuratie, DNS, open poorten en blootliggende bestanden tellen allemaal mee in de score), maar ze zijn wel de fix met de beste verhouding tussen inspanning en resultaat die de meeste websites beschikbaar hebben.

Een goed geconfigureerde site trekt geen aandacht. Geautomatiseerde scanners onderzoeken dagelijks miljoenen sites op ontbrekende headers, open poorten en bekende softwarekwetsbaarheden. Een site die de juiste headers stuurt wordt sneller overgeslagen en minder aangevallen. Dat is geen security through obscurity; het maakt de makkelijke winsten onbeschikbaar.

De continue-monitoring-kant

Headers kunnen terugsakkeren. Een CMS-update, een nieuwe plugin, een servermigratie of een configuratiewijziging van je hostingprovider kan stilletjes een header wegnemen die er gisteren nog stond. De Noroshi-scanner controleert alle vijf de headers bij elke scan en waarschuwt je zodra er één verdwijnt, zodat een onderhoudsmoment niet ongemerkt een securitymoment wordt.

Maak een gratis account aan, voeg je domein toe en zie je huidige headerscore binnen enkele minuten. Gratis plan, geen creditcard nodig.


Geschreven door David Hildering, de engineer achter Noroshi. Meer over Noroshi.