HSTS (HTTP Strict Transport Security, RFC 6797) ist ein einfacher Response-Header, der weitreichende Wirkung hat: einmal vom Browser gespeichert, weigert er sich, die Domain je wieder über HTTP aufzurufen. Das blockt Downgrade-Angriffe, SSL-Strip und falsch konfigurierte Plain-HTTP-Links. Mit dem preload-Mechanismus wird die Sicherung sogar in den Browser-Source-Code eingebaut — ab Werk, ohne ersten Besuch. Dieser Artikel zeigt die Konfiguration, die Stolperfallen und den irreversiblen Charakter.

Was HSTS macht

HTTP hsts-header.txt
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Drei Direktiven:

  • max-age=31536000 — Sekunden, die der Browser sich an die HSTS-Pflicht erinnert (hier: 1 Jahr).
  • includeSubDomains — gilt auch für alle Subdomains.
  • preload — Opt-in für die Browser-Preload-List (siehe unten).

Browser-Verhalten nach Empfang:

  1. Browser speichert: „example.com ist HSTS-aktiviert, gültig bis ...".
  2. Jeder Versuch, http://example.com/... aufzurufen, wird bevor irgendetwas über das Netz geht intern zu https://... umgeschrieben.
  3. Wenn das HTTPS-Zertifikat ungültig ist (abgelaufen, falscher CN, self-signed), gibt es kein Click-Through-Warning mehr — der Browser blockt strikt.

Was HSTS verhindert

1. SSL-Strip-Angriff (Moxie Marlinspike, 2009):

Ein Angreifer im Netzwerk (Café-WLAN, kompromittierter Router) fängt eine HTTP-Anfrage ab und antwortet selbst — der User landet auf einer HTTP-Variante der Seite, die der Angreifer komplett liest und manipuliert. Ohne HSTS sieht der User ein HTTP-Schloss (kein gar keins) und merkt es eventuell nicht.

Mit HSTS: Browser geht direkt zu HTTPS, MitM hat keine Chance, das HTTPS-Setup zu kompromittieren (ohne valides Zertifikat).

2. Klick auf alten http-Link:

Wenn ein User von Mail/Social Media auf http://example.com/foo klickt, würde der erste Roundtrip im Klartext gehen. Mit HSTS macht der Browser direkt HTTPS — keine Klartext-Übertragung.

3. Cookies in versehentlichem HTTP-Context:

Auch wenn der App-Server selbst korrekt zu HTTPS redirected, ist die initiale HTTP-Anfrage des Browsers (mit Cookies) im Klartext gegangen. HSTS verhindert das beim wiederholten Besuch.

Was HSTS nicht verhindert:

  • First-Visit-Vector — der allererste Besuch geht potentiell über HTTP (außer preload).
  • Komplette HTTPS-Kompromittierung — wenn das Zertifikat des Angreifers vom Browser anerkannt wird (verseuchter Root-Store, intern installierte Corporate-CA, vorgehaltenes echtes Cert).

max-age — Strategie

Empfohlene Werte:

max-ageWertWann
601 MinuteAllererster Test einer neuen Konfig
3005 MinutenErste Iteration nach Test
864001 TagStable-Test über mehrere Tage
259200030 TageZwischen-Schritt
315360001 JahrProduktiv-Wert (Mindest-Empfehlung)
630720002 JahrePreload-Liste verlangt

Strategie: schrittweise hochsetzen. Mit kleinem Wert starten (1 Tag), prüfen ob alle App-Endpunkte HTTPS unterstützen, dann auf 1 Jahr erhöhen. Wer direkt mit 1 Jahr startet und einen HTTPS-Bug hat — User sind 1 Jahr lang ausgesperrt, kein Workaround.

Reset durch max-age=0: Wenn die App HSTS auflöst, sendet sie max-age=0. Browser löscht den HSTS-State. User muss aber die Seite besuchen dafür — wer nicht zurückkommt, behält den alten State.

includeSubDomains — Vorsicht

includeSubDomains macht HSTS gültig für alle Subdomains. Klingt gut — aber:

Wenn auch nur eine Subdomain HTTP-only ist, ist sie nach Aktivierung unerreichbar. Beispiele:

  • legacy.example.com läuft noch über HTTP.
  • dev.example.com hat ein selbst-signiertes Zertifikat.
  • cdn.example.com ist auf einem dritten Anbieter, der noch kein HTTPS hat.
  • mail.example.com — manche IMAP-/SMTP-Setups haben Webmail nur über HTTP intern.

Strategie: vor Aktivierung alle Subdomains inventarisieren (Certificate Transparency Logs, DNS-Audits, interne Doku). Erst aktivieren, wenn alle HTTPS sprechen.

Die HSTS-Preload-List

Das First-Visit-Problem löst die Preload-List: Chrome, Firefox, Safari, Edge führen eine Liste von Domains, die ab Werk HTTPS-Only sind — kein erster HTTP-Request möglich.

Submission auf hstspreload.org:

Anforderungen:

  • Gültiges HTTPS-Zertifikat für die Domain.
  • max-age mindestens 31536000 (1 Jahr).
  • includeSubDomains Pflicht.
  • preload-Direktive im Header.
  • HTTP → HTTPS Redirect für die Root-Domain.
  • Alle Subdomains müssen HTTPS sprechen.

Nach Submission: Chromium-Liste wird mit jedem Browser-Release ausgerollt — Firefox, Safari, Edge übernehmen die Chromium-Liste mit Verzögerung von ~Monaten.

Wichtig — Removal ist langsam: Wer aus der Preload-Liste raus will, muss preload aus dem Header entfernen, dann ein Removal-Request stellen. Die Verbreitung der Removal über alle Browser dauert Monate bis Jahre. Preload ist eine sehr langfristige Entscheidung.

Klassische Fehler

1. HSTS auf .dev-/.test-Domains in Production:

Manche TLDs (.dev, .app, .bank, .insurance) sind im Chromium-Source als automatisch HSTS-preloaded definiert. Wer auf myapp.dev als Local-Dev-Domain mit selbst-signiertem Zertifikat arbeitet, hat HTTPS-Pflicht ab Werk. Lokales Setup mit mkcert/HTTPS dev-server ist Pflicht.

2. HSTS gesetzt, aber Subdomain kein HTTPS:

App auf app.example.com setzt HSTS mit includeSubDomains. api.example.com läuft noch über HTTP. Browser nimmt die HSTS-Regel auch für api.example.com an — Request schlägt fehl, API ist down.

3. Falsche Zertifikatskette nach HSTS:

Wenn das HTTPS-Zertifikat ungültig wird (Intermediate-CA fehlt, Wildcard-Cert läuft ab, falscher CN), bekommt der User mit HSTS kein Click-Through. Die Seite ist hart kaputt. Bei kritischen Apps: Cert-Monitoring (siehe Kap 19) und großzügiger Vorlauf für Cert-Renewal.

4. HSTS auf Single Subdomain, dann auf Parent:

Wenn app.example.com HSTS mit includeSubDomains setzt, sich aber nur die Subdomain selbst meint und nicht den Parent — Browser nimmt Subdomain plus deren Subdomains, nicht den Parent. Wer den Parent absichern will, muss HSTS dort setzen.

5. HSTS für IP-Adressen geht nicht:

HSTS ist domain-basiert. https://192.168.1.1 kann nicht mit HSTS gesichert werden.

HSTS-Strip beim First-Visit

Ohne Preload bleibt eine kleine Lücke: der allererste Besuch des Users kann manipuliert werden.

Szenario:

  1. User tippt example.com (ohne Protokoll) in die URL-Leiste.
  2. Browser geht zu http://example.com.
  3. Angreifer im Netzwerk antwortet mit eigener Seite (HTTPS-Strip).
  4. User merkt es eventuell nicht — der Angreifer leitet später auf echtes HTTPS um, hat aber Cookies/Session aus dem ersten Request.

Schutz:

  • Preload-List ist die strukturelle Antwort.
  • HTTPS-Only-Mode im Browser — User-seitig (Chrome, Firefox: Settings → HTTPS-Only). Stand 2026 zunehmend Default.
  • DNS-CAA-Records (RFC 6844) helfen indirekt — schränken ein, welche CA für die Domain Zertifikate ausstellen darf.

HTTPS-Only-Setup neben HSTS

HSTS ist der Header — daneben gehören Server-seitig:

1. Erzwungener Redirect HTTP → HTTPS:

Nginx nginx-http-redirect.conf
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    # TLS-Config ...

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    # ...
}

2. Secure Cookies:

Cookies mit Secure-Flag werden nicht über HTTP übertragen. Plus __Host--Präfix für Auth-Cookies (siehe cookie-flags-und-attribute).

3. CSP upgrade-insecure-requests:

Falls die App noch alte http://-Links im HTML hat (Bilder, iframes, Skripte), kann CSP den Browser anweisen, die alle als HTTPS aufzurufen:

HTTP csp-upgrade-insecure.txt
Content-Security-Policy: upgrade-insecure-requests

Migration-Hilfe — sollte langfristig durch saubere Source-Code-Updates abgelöst werden.

Besonderheiten

HSTS gilt pro Browser-Profil

HSTS-State ist im Browser-Profil gespeichert. Inkognito-Modus, frisch installierter Browser, Reset-of-Browser-Data — alles löscht den HSTS-State. Konsequenz: HSTS schützt den wiederkehrenden User, nicht den frischen Besucher (außer Preload).

Domains in der Chromium-HSTS-Liste finden

Die Chromium-HSTS-Preload-List ist öffentlich. Mit chrome://net-internals/#hsts kann man im laufenden Chrome prüfen, ob eine Domain in der Liste ist und ihren aktuellen HSTS-State sehen.

TLS-Stripping mit Cookie-Hijack als historischer Vector

Vor HSTS war SSL-Strip plus Cookie-Lesen die Standard-Methode in öffentlichen WLANs. Firesheep (Eric Butler, 2010) automatisierte das — Facebook/Twitter-Accounts in fremden Cafés mit einem Klick. HSTS plus universelle HTTPS-Migration haben die Klasse praktisch eliminiert.

HSTS und Custom-Browser-Trust-Anchors

Corporate-Netzwerke installieren oft eigene Root-CAs in Client-Browsern (für TLS-Interception). HSTS allein verhindert das nicht — der MitM-Proxy hat ein vom Client-Browser anerkanntes Zertifikat. HSTS schützt vor unautorisierten Angreifern, nicht vor autorisierten. Wer staatliche/Corporate-Akteure als Threat-Model hat, braucht andere Schichten (siehe Kap 6).

HPKP ist deprecated — kein Pendant für Cert-Pinning im Browser

HTTP Public Key Pinning (HPKP) sollte Cert-Pinning im Browser ermöglichen. Wurde 2017 als instabil abgekündigt und 2018 aus Chrome entfernt. Replacement: Certificate Transparency Logs (passiv) und für eigene Apps Cert-Pinning im Mobile-Client-Code.

HSTS in der `localhost`-Welt

Chrome ignoriert HSTS für localhost und 127.0.0.1. Bei Test-Setups mit Domain wie local.example.com via /etc/hosts greift HSTS — wer mit self-signed Cert testet, wird gesperrt. Workaround: separate Test-Domain ohne HSTS, oder Browser-State manuell löschen.

HSTS und Subdomain-Takeover

Wenn eine Subdomain aufgegeben wird, aber im DNS noch existiert (blog.example.com zeigt auf nicht mehr existierende GitHub-Pages), kann ein Angreifer die Subdomain übernehmen. Mit HSTS includeSubDomains hat der Angreifer das Problem, dass User über HTTP nicht auf seine schadhafte Seite zugreifen — er muss valides HTTPS-Cert für die übernommene Subdomain bekommen, was bei vielen Hosting-Providern (mit Let's Encrypt) trivial ist. HSTS hilft hier nur als zusätzliche Hürde, nicht als kompletter Schutz. Subdomain-Hygiene bleibt nötig.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Secure Headers & Cookies

Zur Übersicht