HTTP Strict Transport Security (HSTS) is een beveiligingsmechanisme dat browsers instrueert om uitsluitend via HTTPS met uw website te communiceren. Zodra een browser de HSTS-header van uw server heeft ontvangen, zet hij elk HTTP-request automatisch om naar HTTPS gedurende de in de header opgegeven periode, ook als de gebruiker expliciet http:// in de adresbalk typt of op een oude HTTP-link klikt.
Dit klinkt misschien als een klein gemak, maar het lost een reëel en gevaarlijk probleem op. Laten we precies doornemen waarom HSTS bestaat, hoe het in de praktijk werkt en wat u als WordPress-site-eigenaar moet weten.
Hoe SSL-stripping-aanvallen werken zonder HSTS
Stelt u zich voor dat een bezoeker zijn laptop opent in een koffiebar en uwsite.com in de browser typt. Zonder HSTS verstuurt de browser eerst een gewoon HTTP-request naar uw server. Uw server reageert vervolgens met een 301-redirect naar https://uwsite.com. Dat eerste HTTP-request is echter volledig onversleuteld. Het reist als platte tekst over het wifinetwerk van de koffiebar.
Een aanvaller op hetzelfde netwerk kan dat eerste onversleutelde request onderscheppen via een techniek die SSL stripping heet. De aanvaller fungeert als proxy: hij onderhoudt een HTTPS-verbinding met uw echte server, maar serveert een gewone HTTP-versie aan het slachtoffer. Vanuit het perspectief van de bezoeker ziet de site er normaal uit (de meeste mensen controleren het hangslotje niet). Ondertussen kan de aanvaller alles meelezen: inloggegevens, formulierinzendingen, sessiecookies en creditcardgegevens.
Dit is geen theoretische aanval. Tools zoals sslstrip zijn sinds 2009 publiekelijk beschikbaar, en SSL stripping behoort nog steeds tot de meest praktische aanvallen op openbare wifinetwerken. HSTS is specifiek bedoeld om dit gat te dichten.
Hoe HSTS uw WordPress-site beschermt
Wanneer uw server de volgende response-header verstuurt:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadslaat de browser deze instructie intern op. Gedurende de volgende 31.536.000 seconden (één jaar) zal hij nooit een HTTP-verbinding met uw domein proberen te maken. Als iets probeert een resource via HTTP te laden, herschrijft de browser dat lokaal naar HTTPS voordat het request het apparaat überhaupt verlaat. Er is geen onversleuteld request meer dat een aanvaller kan onderscheppen.
Deze bescherming werkt op browserniveau, en dat is het cruciale voordeel. Er is geen redirect nodig. Er wordt nooit een onversleuteld request verzonden. De browser weigert simpelweg HTTP te gebruiken voor uw domein.
HSTS-header-directieven uitgelegd
De HSTS-header accepteert drie directieven, en elke heeft een specifiek doel:
max-age: de tijd in seconden die de browser moet onthouden om HTTPS af te dwingen. Gangbare waarden zijn86400(1 dag, handig voor initiële tests),2592000(30 dagen, een redelijk startpunt) en31536000(1 jaar, de aanbevolen productiewaarde). Als u dit op nul zet, stopt de browser onmiddellijk met het afdwingen van HSTS voor uw domein.includeSubDomains: breidt het HSTS-beleid uit naar alle subdomeinen. Dit betekent datcdn.uwsite.com,mail.uwsite.comen elk ander subdomein ook gedwongen worden tot HTTPS. Wees voorzichtig met deze directive: als een subdomein geen HTTPS ondersteunt, wordt het onbereikbaar zodra dit actief is.preload: een signaal dat u uw domein wilt laten toevoegen aan de preload-lijsten van browsers. Hieronder meer hierover.
Het probleem van het eerste bezoek en HSTS-preload-lijsten
HSTS heeft één fundamentele beperking: de browser moet de header minstens één keer ontvangen voordat hij iets kan afdwingen. Bij het allereerste bezoek, voordat de browser ooit uw HSTS-header heeft gezien, is het initiële HTTP-request nog steeds kwetsbaar voor onderschepping. Dit staat bekend als het "first visit problem" of "bootstrap problem".
De HSTS-preload-lijst lost dit op. Het is een lijst van domeinen die hardcoded in de browser zelf zit (Chrome, Firefox, Safari en Edge delen allemaal dezelfde lijst). Als uw domein op de preload-lijst staat, dwingt de browser HTTPS af vanaf de allereerste verbinding, zelfs als de gebruiker uw site nog nooit heeft bezocht.
Om uw domein op de preload-lijst te krijgen, moet u aan alle volgende vereisten voldoen:
- Een geldig HTTPS-certificaat aanbieden op uw root-domein
- Al het HTTP-verkeer doorverwijzen naar HTTPS op dezelfde host
- De HSTS-header op het root-domein versturen met een
max-agevan minimaal31536000(één jaar) - De directive
includeSubDomainsopnemen - De directive
preloadopnemen - Alle subdomeinen moeten HTTPS ondersteunen
U kunt uw domein indienen op hstspreload.org. Houd er rekening mee dat opname op de lijst weken tot maanden kan duren (het wordt meegeleverd met browser-updates) en dat verwijderen even traag verloopt. Zorg dat uw HTTPS-configuratie solide is voordat u indient.
Gangbare max-age-waarden en aanbevolen uitrolstrategie
Het is verleidelijk om meteen voor een max-age van één jaar te kiezen, maar een geleidelijke uitrol is veiliger, vooral voor sites met meerdere subdomeinen of complexe configuraties:
max-age=300(5 minuten): gebruik dit tijdens initiële tests. Mocht er iets misgaan, dan zijn bezoekers slechts vijf minuten vastgezet op HTTPS.max-age=86400(1 dag): een goede vervolgstap zodra u heeft bevestigd dat HTTPS correct werkt.max-age=2592000(30 dagen): ga hierheen na een week of twee stabiele werking.max-age=31536000(1 jaar): de aanbevolen productiewaarde. Dit is ook het minimum dat vereist is voor de preload-lijst.
HSTS instellen op een WordPress-site
WordPress zelf verstuurt de HSTS-header niet standaard. U heeft verschillende opties om hem toe te voegen:
De betrouwbaarste aanpak is om de header op serverniveau toe te voegen. Voeg in Apache het volgende toe aan uw .htaccess-bestand of de virtual-host-configuratie:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"Voeg voor Nginx dit toe binnen uw server-blok:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;Heeft u geen toegang tot de serverconfiguratie (gebruikelijk bij shared hosting), dan kunt u de header toevoegen via PHP in functions.php van uw thema of via een must-use plugin:
add_action('send_headers', function() {
header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
});De aanpak op serverniveau heeft de voorkeur, omdat die geldt voor alle responses, inclusief statische bestanden en foutpagina's, niet alleen voor PHP-gegenereerde pagina's.
Diverse WordPress-beveiligingsplugins bieden ook HSTS-configuratie via hun instellingenpanelen, wat handig kan zijn als u een grafische aanpak verkiest.
Veelvoorkomende valkuilen met HSTS op WordPress
Controleer een aantal zaken voordat u HSTS inschakelt:
- Mixed content: zorg dat alle resources (afbeeldingen, scripts, stylesheets, fonts) via HTTPS worden geladen. HSTS dwingt de hoofdverbinding naar HTTPS, maar als uw content nog naar HTTP-URL's verwijst, blokkeren browsers die resources.
- Vernieuwen van het SSL-certificaat: zodra HSTS actief is, maakt een verlopen certificaat uw site volledig onbereikbaar (in plaats van een omzeilbare waarschuwing te tonen). Stel automatische certificaatvernieuwing in met Let's Encrypt of uw certificaatleverancier.
- Gereedheid van subdomeinen: gebruikt u
includeSubDomains, dan moet elk subdomein een geldig HTTPS-certificaat hebben. Een staging-subdomein op HTTP zal stoppen met werken. - CDN-configuratie: gebruikt u een CDN zoals Cloudflare, zorg dan dat HSTS consistent is geconfigureerd. Cloudflare biedt eigen HSTS-instellingen die uw server-headers kunnen overschrijven.
Wat InspectWP controleert
InspectWP analyseert of uw WordPress-site de response-header Strict-Transport-Security verstuurt. Het rapport beoordeelt de waarde van max-age, controleert op de directive includeSubDomains en signaleert dat de header ontbreekt als deze niet aanwezig is. Een correcte HSTS-header met een lange max-age-waarde (minimaal zes maanden of één jaar) en de directive includeSubDomains wordt aanbevolen voor elke WordPress-site die op HTTPS draait, wat in het hedendaagse web alle sites zouden moeten zijn.