U laat een gratis beveiligingsscan over uw website lopen en krijgt een cijfer terug: een D, of een F. De toelichting staat vol met termen als “Strict-Transport-Security ontbreekt” en “geen Content-Security-Policy”. Uw website werkt prima, er is niets gehackt, en toch lijkt het rapport te zeggen dat er van alles mis is.
Die meldingen gaan over de beveiligingsheaders van uw website. Het zijn korte instructies die uw server meestuurt met elke pagina, en die de browser van de bezoeker vertellen wat wel en niet mag. Ze kosten niets, ze vertragen niets en ze sluiten een reeks aanvallen uit die anders mogelijk zijn. In dit artikel leggen wij uit wat de belangrijkste headers doen, welke u eerst instelt en waar het mis kan gaan.
Wat een header precies is
Als uw browser een pagina opvraagt, stuurt de server niet alleen de pagina zelf terug, maar ook een lijstje met regels erboven. Dat lijstje ziet u nooit, maar de browser leest het wel. Er staat bijvoorbeeld in wat voor soort inhoud er volgt en hoe lang de browser die mag bewaren.
Beveiligingsheaders zijn regels in datzelfde lijstje die iets zeggen over veiligheid. Ze worden ingesteld op de server, in het .htaccess-bestand of in de serverconfiguratie, of via een plugin die ze voor u toevoegt. De browser houdt zich er vervolgens aan. Dat is het hele mechanisme: uw server geeft instructies, de browser voert ze uit. Daarom beschermen headers de bezoeker meer dan de server zelf.
De belangrijkste beveiligingsheaders voor uw website
Strict-Transport-Security (HSTS)
Deze header zegt tegen de browser: gebruik voor deze website voortaan altijd HTTPS, ook als iemand een adres met http:// intypt of een oude link volgt. De browser onthoudt dat voor een ingestelde periode, vaak een jaar. Het voorkomt dat een aanvaller op een openbaar wifi-netwerk de verbinding kan onderscheppen tijdens die eerste onbeveiligde aanvraag.
Voorwaarde is dat uw hele site foutloos op HTTPS werkt, inclusief subdomeinen als u die meeneemt. Zet HSTS pas aan als dat zeker is, want de browser onthoudt de instructie: gaat het certificaat daarna kapot, dan komt niemand er meer in totdat het is opgelost. Begin met een korte periode en verleng die na een paar weken.
Content-Security-Policy (CSP)
Dit is de krachtigste en de lastigste. Een CSP vertelt de browser precies van welke bronnen scripts, stijlen, afbeeldingen en lettertypen mogen worden geladen. Alles wat er niet in staat, wordt geweigerd. Als een aanvaller erin slaagt een stukje kwaadaardig script in uw pagina te krijgen, weigert de browser dat uit te voeren omdat het niet op de lijst staat.
Het lastige is dat een WordPress-site met een handvol plugins scripts laadt van tientallen plekken: Google Fonts, een chatwidget, een kaart, een betaalprovider, statistieken. Een te strenge CSP breekt die functies direct. Daarom stelt u een CSP eerst in op “alleen rapporteren”: de browser blokkeert nog niets, maar meldt wat hij zou blokkeren. Pas als die meldingen kloppen, zet u het beleid scherp.
X-Frame-Options
Deze header bepaalt of uw pagina’s in een frame op een andere website mogen worden getoond. Zonder deze header kan iemand uw inlogpagina of een bestelknop onzichtbaar over zijn eigen pagina heen leggen en bezoekers laten klikken op iets wat ze niet zien; dat heet clickjacking. De waarde SAMEORIGIN staat frames alleen op uw eigen domein toe en is voor bijna elke site de juiste keuze. De modernere variant hiervan is de regel frame-ancestors binnen een CSP.
Drie kleinere, maar nuttige headers
- X-Content-Type-Options: nosniff voorkomt dat de browser zelf gaat raden wat voor bestand hij ontvangt, waardoor een vermomd script niet als script wordt uitgevoerd.
- Referrer-Policy bepaalt hoeveel informatie over uw pagina wordt meegestuurd als een bezoeker naar een andere site klikt. Een waarde als strict-origin-when-cross-origin beschermt de privacy van uw bezoekers zonder statistieken onbruikbaar te maken.
- Permissions-Policy zet browserfuncties uit die uw site niet nodig heeft, zoals camera, microfoon en locatie. Als een ingeladen script die dan wil gebruiken, weigert de browser.
In welke volgorde u ze instelt
- Zorg eerst dat HTTPS overal foutloos werkt. Zonder dat is HSTS gevaarlijk en heeft de rest weinig zin. Hoe u dat grondig regelt, leest u in ons artikel over HTTPS goed instellen.
- Voeg X-Content-Type-Options, X-Frame-Options en Referrer-Policy toe. Deze drie breken vrijwel nooit iets en zijn in vijf minuten geregeld.
- Zet HSTS aan met een korte periode, bijvoorbeeld een week. Verleng naar een jaar als er geen problemen zijn.
- Voeg Permissions-Policy toe voor de functies die u zeker niet gebruikt.
- Bouw als laatste een Content-Security-Policy op in rapportagemodus, en zet die pas scherp na een paar weken meten.
Test na elke stap uw belangrijkste pagina’s: homepage, contactformulier, en bij een webshop de afrekenpagina. Gebruik daarvoor ook een telefoon en een andere browser dan u gewend bent.
Wat u zelf kunt doen en wanneer u hulp vraagt
De eenvoudige headers kunt u zelf toevoegen via een plugin of, met wat meer zekerheid, door uw hostingpartij te vragen ze op serverniveau in te stellen. Veel Nederlandse WordPress-hosters hebben daar een standaardconfiguratie voor. Een CSP is ander werk: die vraagt om iemand die de site kent, het rapport begrijpt en weet welke bronnen legitiem zijn. Bij een webshop met betaalkoppelingen zouden wij dat nooit zonder staging-omgeving doen.
Bij WebMaintor nemen wij de basisheaders mee in de inrichting van websitebeveiliging met firewall en monitoring en meten wij daarna of ze blijven staan, want een hostingverhuizing of een nieuwe cacheplugin kan ze ongemerkt weer weghalen. Gebruikt u Cloudflare, dan kunt u een deel van deze headers ook daar instellen, onafhankelijk van uw hosting; in ons artikel over Cloudflare voor WordPress gaan wij daar dieper op in.
Conclusie
Een slechte score op een headerscan betekent niet dat uw site gehackt is, maar wel dat u een goedkope beschermlaag laat liggen. De meeste headers regelt u in een kwartier, zonder risico. Alleen HSTS en een Content-Security-Policy vragen om zorg en een teststap. Begin bij de kleine, meet, en bouw de rest rustig op.



