headeraudit.nl
← BlogPraktijkgids

Zo lees je een security-scanrapport: waarom twee scanners jouw site anders beoordelen

headeraudit.nl · leestijd 5 minuten

Wij hebben headeraudit.nl door een andere Nederlandse security-scanner gehaald. Die kwam uit op 80% en grade B, met zeven security headers opgesomd onder de labels HIGH en MEDIUM. Onze eigen scanner geeft dezelfde site 95% en een A+. Beide tools deden één server-side request naar dezelfde URL en zagen dus letterlijk dezelfde response headers.

Dat verschil is geen smaakkwestie. Het laat zien dat de score onder aan een rapport minder zegt dan de manier waarop dat rapport is opgebouwd — en dat is precies waar je als lezer op moet letten.

Het experiment: dezelfde site, twee rapporten

Dit staat er daadwerkelijk op onze origin:

strict-transport-security: max-age=63072000; includeSubDomains; preload
content-security-policy: default-src 'self'; script-src 'self' 'nonce-…' 'strict-dynamic';
  object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self';
  upgrade-insecure-requests;
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=()
cross-origin-opener-policy: same-origin
cross-origin-resource-policy: same-site

In het andere rapport staan HSTS, Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, CSP frame-ancestors, Referrer-Policy en Permissions-Policy allemaal als losse regel, elk met een ernst-label en een alinea die uitlegt wat er misgaat als de header ontbreekt. Ze zijn alle zeven aanwezig.

Waar het verschil vandaan komt

Een rapport zonder status is geen rapport

De belangrijkste informatie in een scanregel is niet de uitleg, maar het antwoord op de vraag: is dit gelukt of niet? In de PDF die wij terugkregen ontbrak die status volledig. Elke check kreeg dezelfde opmaak — kop, ernst-label, "Wat is dit?", "Risico:" — of hij nu slaagde of faalde. In de webinterface stond er ongetwijfeld een groen vinkje bij, maar de PDF is nu juist het bestand dat je doorstuurt naar een klant, een auditor of je directeur.

Vraag jezelf bij elk rapport af of je per regel kunt zien wat de uitkomst was. Kan dat niet, dan lees je een brochure, geen rapport.

Ernst hoort bij de bevinding, niet bij de check

In hetzelfde rapport stond de regel "HTTPS Beschikbaar" met het label CRITICAL. Onze site draait volledig op HTTPS. Het label sloeg dus niet op een probleem, maar op het gewicht dat de check zou hebben gehad als hij was gefaald.

Dat onderscheid klinkt academisch, maar het bepaalt of een rapport bruikbaar is. Een lijst met tien CRITICAL-regels waarvan er nul een probleem beschrijven, traint lezers om ernst-labels te negeren. En dat is precies het moment waarop een echte kritieke bevinding wordt gemist.

Een checklist veroudert

X-XSS-Protection stond in het rapport als ontbrekende header. Die header schakelde een XSS-filter in oudere browsers in. Chrome heeft die filter in 2019 verwijderd omdat hij zelf lekken introduceerde, en de huidige aanbeveling is om de header weg te laten of op 0 te zetten.

Wij tellen de afwezigheid van X-XSS-Protection dus als een geslaagde check, met deze toelichting: "Afwezig — prima: moderne browsers negeren deze header toch, en de oude XSS-auditor die hij inschakelde was zelf een risico." Een scanner die je punten aftrekt voor het níét zetten van een afgeraden header, werkt met een checklist die al jaren niet is aangeraakt.

Checks moeten bij je stack passen

Het rapport controleerde ook of wp-config.php beschermd was. headeraudit.nl draait op Next.js, serverless, zonder PHP en zonder publiek filesystem. Datzelfde geldt voor de controles op .git, .env, phpinfo.php en backup-bestanden: die kunnen op deze architectuur überhaupt niet worden geserveerd.

Het waren stuk voor stuk CRITICAL-regels. Tien in totaal. Allemaal niet van toepassing, en niet als zodanig gemarkeerd.

Vier vragen die je aan elk scanrapport stelt

  1. Kan ik per regel zien of de check slaagde, faalde of niet van toepassing was? Zo niet, dan is de score niet te controleren.
  2. Staat de aangetroffen waarde erbij? Een bevinding zonder de daadwerkelijke header-inhoud is een bewering, geen bewijs.
  3. Zitten er checks in die bij mijn stack niet kunnen bestaan? Dat verraadt een generieke lijst zonder detectie.
  4. Slaat het ernst-label op mijn situatie of op de check in het algemeen? Alleen het eerste is bruikbaar.

Wat wij zelf missen

Transparantie werkt alleen als je ook je eigen tekortkomingen publiceert. Onze A+ is 106 van de 112 punten. De zes ontbrekende punten zitten in Cross-Origin-Embedder-Policy, die wij niet zetten omdat we geen cross-origin isolatie nodig hebben. En onze scanner meldt terecht één information leak: Server: Vercel. Dat is de header van onze hostingprovider, die we op dat platform niet kunnen onderdrukken.

Geen enkele scanner, inclusief die van ons, geeft een compleet beeld van je beveiliging. Een header-audit dekt de instructies die je server aan de browser meegeeft — niet je applicatielogica, je afhankelijkheden of je toegangsbeheer. Een tool die suggereert dat een A+ betekent dat je veilig bent, verkoopt je hetzelfde soort onnauwkeurigheid als een tool die met tien valse CRITICAL-regels zwaait.

Test je site nu← Alle headers in detail
Zo lees je een security-scanrapport: waarom twee scanners jouw site anders beoordelen — headeraudit.nl