Kurz erklärt
HSTS steht für HTTP Strict Transport Security und ist ein Antwort-Header,
den dein Webserver an den Browser sendet. Damit teilst du dem Browser mit: "Ab sofort und
für die nächsten X Sekunden lädst du diese Domain ausschließlich über HTTPS — egal ob der
Nutzer auf einen http://-Link klickt
oder die Adresse ohne Protokoll eingibt." Der Browser merkt sich diese Anweisung und
verbindet sich beim nächsten Besuch direkt verschlüsselt.
Welches Problem löst HSTS?
Ohne HSTS läuft beim ersten Besuch typischerweise dieser Ablauf: Nutzer tippt
deinedomain.de in den Browser, der
schickt eine HTTP-Anfrage, der Server antwortet mit einem HTTPS-Redirect. Genau diese
erste, unverschlüsselte Anfrage ist die Schwachstelle: Ein Angreifer im selben WLAN kann
den Redirect abfangen, sich als deine Webseite ausgeben und die HTTPS-Verbindung nur
zwischen sich und deinem Server aufbauen — der Nutzer redet weiter unverschlüsselt mit
dem Angreifer (SSL-Stripping). Mit HSTS ignoriert der Browser den HTTP-Versuch und macht
sofort HTTPS.
Aufbau des Headers
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age=31536000— wie lange (in Sekunden) der Browser sich die HSTS-Anweisung merkt. 31536000 = 1 Jahr, das ist der gängige Wert. Werte unter 6 Monaten gelten als zu kurz.includeSubDomains— die Anweisung gilt auch für alle Subdomains (z. B.api.deinedomain.de,blog.deinedomain.de). Wichtig: alle Subdomains müssen dann tatsächlich HTTPS sprechen.preload— du beantragst Aufnahme in die HSTS-Preload-Liste der Browser. Damit ist HTTPS schon beim allerersten Besuch erzwungen, bevor der Browser den Header je gesehen hat.
HSTS Preload
Die Preload-Liste
ist hartkodiert in Chrome, Firefox, Safari, Edge. Wer dort eingetragen ist, wird vom
Browser nie wieder über HTTP angefragt — auch nicht beim allerersten Besuch. Voraussetzungen:
gültiges Zertifikat, alle Subdomains via HTTPS, max-age
mindestens 31536000 (1 Jahr), includeSubDomains
und preload gesetzt.
Risiken
HSTS ist fast nicht mehr rückgängig zu machen. Wenn du max-age=31536000; includeSubDomains
ausrollst und merkst, dass eine Subdomain gar kein HTTPS hat — diese Subdomain ist für
ein Jahr unerreichbar, bis bei jedem einzelnen Besucher der Cache abläuft.
Empfehlung: Stufenweise vorgehen.
- Zuerst
max-age=300(5 Min) ohneincludeSubDomains. - Nach einer Woche
max-age=86400(1 Tag). - Alle Subdomains auf HTTPS bringen, dann
includeSubDomainsergänzen. - Schließlich
max-age=31536000und ggf.preload.
Konfigurationsbeispiele
nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Apache:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Cloudflare: Im Dashboard unter SSL/TLS → Edge-Certificates → HTTP Strict Transport Security (HSTS).