Was Strict-Transport-Security tut
Ohne HSTS beginnt fast jeder Besuch mit einer unverschlüsselten Anfrage: Der Nutzer tippt beispiel.de ein, der Browser ruft http://beispiel.de auf und folgt dem Redirect auf HTTPS. Dieser erste Request ist angreifbar. Im öffentlichen WLAN kann jemand den Redirect abfangen und den Nutzer auf einer HTTP-Kopie der Seite halten.
Der Header Strict-Transport-Security sagt dem Browser: Sprich mit dieser Domain für die angegebene Zeit ausschließlich HTTPS. Ab dem ersten erfolgreichen HTTPS-Besuch wandelt der Browser jede http://-Adresse intern in https:// um, bevor er überhaupt eine Verbindung aufbaut. Zertifikatsfehler lassen sich bei HSTS-Domains außerdem nicht mehr wegklicken. Der Header wird nur über HTTPS beachtet, über HTTP ignoriert ihn der Browser.
Strict-Transport-Security: max-age=31536000; includeSubDomainsmax-age schrittweise erhöhen
max-age ist die Zeit in Sekunden, für die sich der Browser die Regel merkt, und sie wird bei jedem Besuch erneuert. Genau darum solltest du nicht sofort mit einem Jahr starten: Stellt sich nach dem Setzen heraus, dass eine Ressource nur über HTTP erreichbar ist, haben alle Besucher der letzten Tage die Sperre bereits ein Jahr lang im Browser.
- Mit max-age=300 (fünf Minuten) beginnen und die Website inklusive aller eingebundenen Ressourcen, Formulare und Weiterleitungen testen.
- Auf max-age=604800 (eine Woche) erhöhen und einige Wochen beobachten, ob Support-Anfragen kommen.
- Auf max-age=31536000 (ein Jahr) gehen. Das ist der Wert, den Browser und die Preload-Liste als Minimum erwarten.
includeSubDomains: Alle Subdomains, wirklich alle
Mit includeSubDomains gilt die Regel für jede Subdomain der Domain, auf der der Header gesetzt wurde. Wird er auf beispiel.de gesetzt, betrifft er www., shop., intranet., webmail., dev. und jede Subdomain, die jemand in fünf Jahren anlegt. Jede davon braucht dann ein gültiges Zertifikat, sonst ist sie im Browser unerreichbar, ohne Möglichkeit, die Warnung zu überspringen.
Das trifft in der Praxis interne Systeme: Das Intranet unter intranet.beispiel.de, das nur per HTTP im Firmennetz läuft, das Webmail des Hosters auf webmail.beispiel.de mit selbstsigniertem Zertifikat, die Staging-Umgebung auf dev.beispiel.de. Erst wenn du alle Subdomains inventarisiert hast und jede sauberes TLS hat, ist includeSubDomains sicher. Ohne includeSubDomains gilt der Header nur für genau den Host, der ihn gesendet hat.
Preload: Praktisch unumkehrbar
Auch mit HSTS bleibt der allererste Besuch ungeschützt, weil der Browser den Header noch nicht kennt. Die Preload-Liste löst das: Chrome, Firefox, Safari und Edge liefern eine fest eingebaute Liste von Domains aus, für die HTTPS von Anfang an erzwungen wird. Aufgenommen wirst du über hstspreload.org.
Die Anforderungen sind streng: gültiges Zertifikat, Redirect von HTTP auf HTTPS auf demselben Host, alle Subdomains über HTTPS, und der Header auf der Hauptdomain muss max-age von mindestens einem Jahr, includeSubDomains und die Direktive preload enthalten. Die Liste ist in Browser-Releases eingebaut. Ein Antrag auf Entfernung dauert Monate, bis er bei allen Nutzern ankommt, und manche Browserversionen werden nie aktualisiert. Preload ist deshalb für Domains gedacht, die dauerhaft und komplett auf HTTPS laufen, nicht für Kunden, die nächstes Jahr vielleicht den Hoster wechseln.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadDie Fallstricke
HSTS unterscheidet sich von anderen Headern dadurch, dass er im Browser des Nutzers lebt, nicht auf dem Server. Was du einmal ausgeliefert hast, kannst du nicht zurückholen.
- Eine Subdomain ohne Zertifikat ist nach includeSubDomains komplett unerreichbar, und der Nutzer kann die Warnung nicht überspringen.
- Du kannst HSTS nicht "abschalten". Entfernst du den Header, behalten Browser die Regel bis zum Ablauf von max-age. Der einzige Weg ist, max-age=0 auszuliefern und zu warten, bis jeder Nutzer die Seite einmal besucht hat.
- Ein abgelaufenes Zertifikat ist bei einer HSTS-Domain ein Totalausfall, weil der Browser keinen Ausnahme-Button mehr anbietet.
- Ein Umzug zu einem Hoster, der Subdomains nur per HTTP bedient, scheitert an den Browsern der Bestandskunden.
- Der Header muss auf jeder HTTPS-Antwort gesetzt sein, auch auf Redirects und Fehlerseiten, sonst verlängert sich max-age nicht zuverlässig.
HSTS setzen: nginx, Apache, Caddy, Cloudflare
Der Header gehört in den HTTPS-Serverblock, nie in den HTTP-Block. Bei nginx ist das Schlüsselwort always wichtig, sonst fehlt der Header auf Fehlerseiten. Bei Apache muss mod_headers aktiv sein. Caddy setzt HTTPS automatisch, aber HSTS nicht, der Header muss explizit rein. Bei Cloudflare findest du HSTS unter SSL/TLS, Edge Certificates, und Cloudflare zeigt dort ausdrücklich eine Warnung, bevor du ihn aktivierst.
# nginx (im server-Block mit listen 443 ssl)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Apache (im VirtualHost *:443, mod_headers)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# Caddy (Caddyfile)
beispiel.de {
header Strict-Transport-Security "max-age=31536000; includeSubDomains"
}Prüfe das Ergebnis danach von außen mit dem HTTP Header Checker oder mit curl -sI https://beispiel.de. Der Header muss in der HTTPS-Antwort erscheinen, und nur dort.
HSTS ersetzt den Redirect nicht
Ein häufiges Missverständnis: Mit HSTS könne man den Redirect von HTTP auf HTTPS weglassen. Das Gegenteil ist der Fall. Der allererste Besuch eines neuen Nutzers und jeder Besuch nach Ablauf von max-age kommt per HTTP an, und dort muss ein 301 auf HTTPS stehen, sonst sieht der Browser den Header nie. Auch die Preload-Liste verlangt diesen Redirect ausdrücklich.
Die richtige Reihenfolge ist also: HTTP-Anfrage, 301 auf dieselbe URL mit https://, HTTPS-Antwort mit dem HSTS-Header. Ab dann übernimmt der Browser und macht den Redirect intern, ohne je wieder Port 80 zu berühren.
Häufige Fragen
- Kann ich HSTS nur auf www.beispiel.de setzen, nicht auf beispiel.de?
- Ja, aber dann gilt er auch nur dort. Für die Preload-Liste und für einen vollständigen Schutz muss der Header auf der Hauptdomain gesetzt sein, weil includeSubDomains von dort aus nach unten wirkt, nicht von www. aus nach oben.
- Wie werde ich HSTS wieder los, wenn ein Kunde zurück auf HTTP muss?
- Den Header mit max-age=0 ausliefern und die Seite weiterhin über HTTPS erreichbar halten, bis alle regelmäßigen Nutzer sie einmal besucht haben. Bei Preload zusätzlich die Entfernung bei hstspreload.org beantragen und mit Monaten rechnen. Ein Rückweg auf HTTP ist heute aber fast nie nötig.
- Hat HSTS Einfluss auf SEO?
- Nicht direkt. Indirekt spart der Browser den HTTP-Umweg und die Seite lädt beim Wiederbesuch minimal schneller. Wichtiger ist, dass HTTPS überhaupt sauber läuft, und genau das erzwingt HSTS.