Hoe deze controle werkt
Deze controle treedt alleen op als je site de header Strict-Transport-Security al verstuurt; ontbreekt hij helemaal, dan meldt de headerscanner dat. Scanaris leest de waarde en controleert twee dingen: dat max-age minstens een jaar is (31536000 seconden) en dat includeSubDomains erin staat. Ontbreekt een van beide, dan opent hij een bevinding met lage ernst en het detail. Laag, omdat een korte of gedeeltelijke HSTS nog steeds iets beschermt; maar hij laat gaten open die een aanvaller kan benutten.
Wat HSTS doet en waarom beide attributen
Wanneer de browser deze header over HTTPS ontvangt, noteert hij je domein in een interne lijst en zet hij, gedurende de tijd in max-age, elke poging om naar http:// te gaan om in https:// voordat hij iets verstuurt. Dat haalt het eerste onversleutelde verzoek weg dat een omleiding niet kan vermijden. Een max-age van een paar uur of dagen laat de gebruiker bij elke afloop onbeschermd; vandaar het minimum van een jaar. Zonder includeSubDomains kan een aanvaller watdanook.jouwdomein.nl via HTTP aanspreken en, door hoe domeincookies werken, cookies stelen of plaatsen die voor de hoofdsite gelden.
Hoe je het oplost
De aanbevolen waarde:
Strict-Transport-Security: max-age=31536000; includeSubDomains
- Vercel: zet hem standaard op aangepaste domeinen; als je
vercel.jsonofnext.configgebruikt voor andere headers, voeg hem daar met deze waarde toe. - Netlify: in het bestand
_headers, onder/*. - Nuxt: in
routeRulesvannuxt.config, regel'/**'. - nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;in hetserver-blok van 443. - Express:
helmet.hsts({ maxAge: 31536000, includeSubDomains: true }).
Voordat je includeSubDomains toevoegt, bevestig dat al je subdomeinen HTTPS serveren: het beheerpaneel, de API, de blog bij een andere aanbieder, het mailsubdomein als het een website heeft. Elk subdomein dat alleen via HTTP antwoordt, stopt met werken in browsers die de header al hebben gezien, en er is geen weg terug totdat max-age verloopt. Bij twijfel begin je met max-age=86400 en zonder subdomeinen, controleer je, en verhoog je de waarde als alles werkt.
Preload
Met preload en een max-age van minstens een jaar kun je opname van je domein aanvragen in de lijst die Chrome, Firefox en Safari meeleveren: dan gaat zelfs het eerste bezoek niet via HTTP. Dat is het gebruikelijke verschil tussen een A en een A+ in analysetools. Maar het is een bijna onomkeerbare verbintenis (van de lijst af komen duurt maanden), dus doe het alleen als het hele domein al een tijd zonder incidenten op HTTPS draait.
Controleer of het opgelost is
curl -sI https://jouwdomein.nl | grep -i strict-transport
Er moet een max-age van 31536000 of meer en includeSubDomains verschijnen. Controleer op de openbare URL: als je een CDN ervoor hebt, moet die hem versturen.
Veelgestelde vragen
Vervangt HSTS de omleiding van HTTP naar HTTPS?
Nee. De header komt alleen via HTTPS aan, dus het eerste bezoek heeft de omleiding nog steeds nodig. Ze vullen elkaar aan: de omleiding voor de eerste keer, HSTS voor alle volgende.
Ik heb een intern subdomein dat alleen via HTTP werkt.
Zet dan geen includeSubDomains voordat je het hebt gemigreerd, en accepteer intussen de bevinding met lage ernst. Een onversleuteld subdomein is een reëel risico voor de domeincookies, dus de migratie is de moeite waard.
Wat gebeurt er als ik het verkeerd configureer?
Browsers die de header hebben ontvangen, houden het beleid aan tot het verloopt. Je kunt max-age=0 sturen om ze te vragen het te vergeten, maar alleen wie via HTTPS terugkomt ziet dat. Daarom is het beter met korte waarden te beginnen.