Vandaag begeleidden we iemand van nul hoe je met een commando de security van een willekeurige website kunt beoordelen. Geen tools installeren, geen account, geen scanner. Gewoon een regel in de terminal en je ziet dingen waar de meeste bedrijven hun ogen voor sluiten.
We draaiden het commando op tcaisolutions.nl. Binnen drie seconden stond de output op het scherm, en voor iemand die nooit eerder naar HTTP onder de motorkap had gekeken, was het een eye-opener. Niet omdat het ingewikkeld was. Juist omdat het simpel bleek. Alles wat een website over zichzelf verraadt aan de buitenwereld staat in een paar regels tekst die je server meestuurt bij elk bezoek.
Die regels heten HTTP response headers. Sommige zijn onschuldige meta-info, zoals welke server er draait of hoe de cache werkt. Andere zijn het verschil tussen "deze website is veilig tegen bekende aanvallen" en "deze website ligt open voor iedereen die weet waar hij moet kijken".
In deze post laten we zien hoe je het zelf kunt doen, welke zes headers iedere moderne website zou moeten hebben, wat er gebeurt als ze ontbreken, en hoe de headers van tcaisolutions.nl er zelf uit zien. Inclusief het stukje waar we zelf nog iets zou willen verbeteren.
Wat er gebeurt als je een URL opent
Als je in je browser een webadres intypt, gebeurt er iets wat je nooit ziet. Je browser stuurt een berichtje naar de server van de website. Dat berichtje bevat dingen zoals welke pagina je wilt, welke taal je spreekt, en welke browser je gebruikt. De server leest die vraag, zoekt de pagina op, en stuurt een antwoord terug.
Dat antwoord bestaat uit twee delen. Eerst een stapel regels met meta-informatie, de response headers. Daarna de eigenlijke inhoud van de pagina, de HTML die je browser tekent.
Je ziet normaal alleen het tweede deel. De browser verwerkt de headers stilletjes op de achtergrond, doet er iets mee, en toont je de pagina alsof die headers niet bestaan. Maar elk bezoek aan elke website levert die headers op, en wie ze leest, leert veel over hoe die website zichzelf verdedigt.
Een commando, alle informatie
Om die headers te zien zonder alle browser-magie eromheen, gebruik je curl. Dat is een commandline tool die al sinds 1996 op praktisch elk Linux, macOS en modern Windows systeem staat. Op Windows is het curl.exe. Op de meeste andere systemen gewoon curl.
Het commando is drie karakters plus een URL:
curl -I https://tcaisolutions.nl/
De -I zegt tegen curl: "ik wil alleen de response headers zien, niet de HTML erachter". Drie seconden later staat er zoiets op je scherm:
HTTP/2 200
server: cloudflare
strict-transport-security: max-age=31536000; includeSubDomains; preload
content-security-policy: default-src 'self'; script-src 'self' ...
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(), payment=()
Dat is het. Geen installatie, geen login, geen accounts. Elke website ter wereld geeft je die headers gratis als je er om vraagt, en met die paar regels weet je hoe serieus de eigenaar security neemt.
De zes headers die iedere moderne website moet hebben
Niet alle headers zijn even belangrijk. Er zijn tientallen mogelijke response headers, maar voor security zijn er zes die het verschil maken tussen "verdedigd" en "uitgekleed". We leggen ze uit in de volgorde van hoe vaak we ze missen bij Nederlandse MKB-websites.
1. Strict-Transport-Security (HSTS)
Deze header zegt tegen de browser van je bezoeker: "gebruik mij alleen via HTTPS, niet via HTTP, en onthoud dat voor de komende 12 maanden". Zonder HSTS kan een aanvaller die tussen de bezoeker en je server zit, de verbinding stiekem terugschakelen naar de onversleutelde versie van je site. Wat daar dan gebeurt, ziet de bezoeker niet. Zijn login-gegevens, zijn sessie, zijn betaalgegevens, alles kan worden afgeluisterd.
Als je HSTS goed hebt staan, weigert de browser simpelweg om via HTTP te praten met jouw domein. De aanval werkt niet meer.
2. Content-Security-Policy (CSP)
Dit is de lastigste header om goed in te stellen, en ook de belangrijkste. CSP is een lijstje dat de browser vertelt: "alleen scripts van deze bronnen mogen draaien op mijn site, alleen stijlen vanaf die plek, alleen afbeeldingen van daar". Als een aanvaller erin slaagt om kwaadaardige JavaScript in jouw pagina te injecteren (bijvoorbeeld via een reactieformulier waar je vergeten bent de input te filteren), blokkeert de browser die code omdat hij niet op de toegestane lijst staat.
Zonder CSP is elke Cross-Site Scripting kwetsbaarheid direct exploitabel. Met CSP moet de aanvaller nog door een extra laag verdediging heen.
3. X-Frame-Options
Deze header bepaalt of jouw site in een iframe op andermans site mag worden geladen. Waarom is dat belangrijk? Clickjacking. Een aanvaller maakt een eigen website, laadt jouw site onzichtbaar in een iframe erover, en plaatst knoppen op zijn eigen site die in werkelijkheid klikken genereren op jouw site. De bezoeker denkt dat hij op de pagina van de aanvaller klikt, maar hij klikt in werkelijkheid op jouw login-knop, jouw delete-account-knop, jouw betaal-knop.
Met X-Frame-Options: SAMEORIGIN kan alleen jij zelf jouw site in een iframe laden. Andere domeinen worden geblokkeerd. Clickjacking werkt niet meer.
4. X-Content-Type-Options
Kort maar krachtig. De waarde hoort altijd nosniff te zijn, en het zegt tegen de browser: "als ik je vertel dat dit bestand een PDF is, accepteer dat. Ga niet proberen te raden of het stiekem HTML met JavaScript is."
Zonder deze header kan een aanvaller een bestand uploaden dat eruit ziet als een onschuldige PNG of PDF, maar dat door de browser als JavaScript wordt geinterpreteerd en uitgevoerd. Een klassieke route voor persistentie na een file-upload bug.
5. Referrer-Policy
Wanneer iemand op een link op jouw site klikt naar een andere site, stuurt de browser standaard informatie mee over waar ze vandaan komen. Dat heet de Referer header. Zonder controle gaat daarin de complete URL, inclusief query parameters. Als die parameters gevoelige informatie bevatten (zoek-termen van klanten, sessie-tokens, wachtwoord-reset links), lek je die naar elke externe site waar je naar linkt.
Referrer-Policy: strict-origin-when-cross-origin zegt: "deel alleen mijn domein, niet het volledige pad". Interne paden en queryparameters blijven privé.
6. Permissions-Policy
De nieuwste van de zes. Deze header bepaalt welke browser-features jouw site mag gebruiken: camera, microfoon, GPS, betaal-API, en meer. Door expliciet te zeggen "nee, ik heb geen van deze features nodig", voorkom je dat een gecompromitteerde script op je pagina opeens toegang vraagt tot de webcam van je bezoeker. Defensief programmeren op het diepste niveau.
De headers van tcaisolutions.nl ontleed
We gaan niet doen alsof onze eigen website perfect is, dus laten we je de echte output zien. Dit is wat curl -I https://tcaisolutions.nl/ bij ons oplevert, regel voor regel.
strict-transport-security: max-age=31536000; includeSubDomains; preload
HSTS voor een jaar, ook voor alle subdomeinen, en in de browser-preload-lijst. Dit is de beste variant. Goed.
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://chat.tsssupport.nl; ...
CSP is aanwezig, met externe bronnen op de juiste witte lijst. Maar let op het stukje 'unsafe-inline' in de script-src directive. Dat betekent dat inline JavaScript in onze HTML nog mag draaien. Dat is geen ramp, maar het is ook geen ideaal. In een perfecte wereld zou alle JavaScript in externe bestanden staan met een nonce of hash die per pagina wordt gegenereerd, en zou 'unsafe-inline' weg kunnen. Bij ons staat het er omdat sommige third-party integraties het nog nodig hebben. Het staat op onze lijst van dingen om op termijn op te lossen.
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(), payment=()
Deze vier staan correct. Clickjacking beschermd, MIME sniffing uitgeschakeld, referrer netjes beperkt, en we hebben expliciet aangegeven dat onze site geen camera, microfoon, GPS of payment API nodig heeft. Als er ooit een gecompromitteerde script binnenkomt, krijgt die geen toegang tot die gevoelige browser-features.
Is het perfect? Nee. Die 'unsafe-inline' moet ooit weg. Is het beter dan 90% van de Nederlandse MKB-sites die we checken? Ja. En dat is precies ons punt.
Waarom dit jouw bedrijf aangaat
Je kunt denken: "dit klinkt technisch, dit is iets voor mijn developer". Dat klopt deels. Maar het is ook iets wat jou, als ondernemer, aangaat om vier concrete redenen.
Eerste reden: ontbrekende security headers verhogen direct het risico op XSS en clickjacking. Een aanvaller die via een contactformulier JavaScript kan injecteren, kan daarmee sessies stelen, gebruikers omleiden naar phishing-pagina's, of namens hen acties uitvoeren. Dit is geen theorie. Dit is de meest voorkomende klasse van web-aanvallen.
Tweede reden: bij due diligence van grotere klanten, partners of investeerders wordt je site automatisch gescand. Tools zoals SecurityHeaders.com geven elke site een score van A tot F. Kom je thuis met een D of F, dan is dat een rood signaal. Veel B2B contracten vereisen tegenwoordig expliciet dat je "industry-standard security headers" hebt geimplementeerd.
Derde reden: NIS2 en andere compliance frameworks verwachten passende technische maatregelen. Security headers zijn een van de goedkoopste, meest zichtbare voorbeelden van zo'n maatregel. Ze staan in geen enkele richtlijn expliciet, maar als een auditor vraagt wat je doet aan web-security en je begint met "we hebben CSP en HSTS correct geconfigureerd", ben je meteen een stap voor.
Vierde reden: het kost weinig. Deze hele set headers correct instellen is een kwestie van een paar regels configuratie op je webserver of in je CDN. Een uur werk voor iemand die weet wat hij doet, en geen onderhoudslast daarna. Het voordeel-over-kosten ratio is absurd gunstig.
Zelf checken in 30 seconden
Als je nu je eigen site wilt checken, heb je twee opties.
De snelle manier: ga naar securityheaders.com, typ je domein in, en je krijgt binnen een seconde een letter-score en een lijst met wat ontbreekt. Geen installatie, geen account. Prima voor een eerste indruk.
De directe manier: open een terminal (op Windows PowerShell of Git Bash, op macOS of Linux gewoon Terminal) en typ curl -I https://jouwdomein.nl/. Je ziet dan exact wat jouw server stuurt, zonder tussenkomst van een externe tool. Vergelijk de output met de zes headers hierboven. Wat staat er? Wat mist?
Als je de hele lijst mist, zit je site waarschijnlijk direct achter een standaard webserver-configuratie die nooit is aangepast. Niet zeldzaam. En ook niet acceptabel meer in 2026.
Wat je nu kunt doen
Twee richtingen, afhankelijk van wat je zoekt.
Wil je begrijpen hoe security werkt en dit zelf leren onderzoeken? De academy van TCAI Solutions leert je vanaf nul. Commando's, tools, oefeningen, echte voorbeelden. Je leert niet alleen de theorie, je past het toe op echte doelwitten onder begeleiding. Meld je aan voor de academy
Of wil je gewoon dat het geregeld is, zonder zelf in de techniek te duiken? KECIAI, onze dochteronderneming voor development en webdiensten, neemt security-configuraties zoals deze van A tot Z over. Je hoeft niets van de details te weten. keciai.nl
Je eigen headers checken kost 30 seconden. De rest van je security niet, maar dit eerste stapje wel. Begin er vandaag mee.