HSTS – HTTP Strict Transport Security: Hast’s schon?
HSTS steht für HTTP Strict Transport Security und ist ein HTTP-Header, den Webseiten nutzen sollten die per HTTPS erreichbar sind.
Wenn ein Benutzer in seinen Browser „webseite.de“ eintippt wird der Browser zuerst versuchen die Webseite unverschlüsselt per HTTP zu erreichen. Genau das ist aber ein Schwachpunkt wenn man sich in einem unsicheren Netzwerk aufhält oder befürchtet, dass irgendwo auf dem Weg zum Zielserver jemand den Request abfangen und verändern könnte (Hallo NSA!), dann sollte man vermeiden eine Webseite unverschlüsselt per HTTP aufzurufen die auch per HTTPS erreichbar ist. Dazu gibt es beispielsweise das Firefox-Addon HTTPS Everywhere, in dem eine Liste eingebaut ist mit Domains, die besser verschlüsselt angesurft werden sollten. Wer nicht auf dieser Liste enthalten ist oder auch Besuchern, die dieses Firefox-Addon nicht installiert haben, mehr Sicherheit bieten möchte, nutzt HSTS.
Fast niemand tippt bei einer Seite, die per HTTPS erreichbar ist, immer brav manuell „https://webseite.de“ ein, die meisten schreiben einfach „webseite.de“ und werden dann vom Webserver automatisch auf die HTTPS-Variante weitergeleitet.
Dieser unverschlüsselte HTTP-Request, der stattfindet, ist ein Sicherheitsproblem, denn ein Angreifer kann das abfangen und dem Besucher z.B. eine Loginseite anzeigen oder ihn irgendwohin weiterleiten oder oder. Wie bekommen wir es nun also hin dass ein Besucher, der nur „webseite.de“ eintippt, sofort auf der verschlüsselten Variante landet? Der Webserver muss dem Browser beibringen, dass diese Webseite bitte in Zukunft (für eine begrenzte Zeit) immer nur verschlüsselt aufgerufen werden darf, auch wenn es irgendwo einen Link im Internet gibt auf http://webseite.de, dann möge der Browser sich bitte daran erinnern dass er gelernt hat, webseite.de immer verschlüsselt aufzurufen.
Der Header
Da kommt nun also HSTS ins Spiel. Der Header, den ein Webserver senden kann, sieht beispielsweise so aus:
Strict-Transport-Security: max-age=31536000
Damit sagt die Webseite dem Browser des Besuchers, dass diese Webseite für die nächsten 12 Monate IMMER nur verschlüsselt besucht werden darf. Dann kann der Besucher gern auf http-Links klicken oder lässig „webseite.de“ eintippen, die Kommunikation mit dem Webserver ist für 12 Monate immer verschlüsselt. Man muss sich als Webseitenbetreiber im Klaren sein dass dann mindestens für die nächsten 12 Monate die Webseite auch per HTTPS erreichbar sein MUSS, sonst bekommen die Besucher eine Fehlermeldung.
Soll nicht nur eine einzelne (Sub)Domain so abgesichert werden gibt es noch den Parameter „includeSubDomains“. So braucht es nur einen Besuch der Webseite (über einen sicheren Kanal), und der Browser wird in Zukunft auch alle Subdomains nur noch verschlüsselt kontaktieren. Wichtig ist auch hierbei dass dann für diese Zeit alle Dienste auf allen Subdomains verschlüsselt zu erreichen sind, also auch adserver.webseite.de, blog.webseite.de und alle anderen Subdomains, die man eigentlich nicht schützen müssten oder wollte.
Strict-Transport-Security: max-age=31536000; includeSubDomains
Essenziell wichtig bei diesem Header ist es natürlich dass der Besucher die Seite einmalig korrekt per HTTPS ansurft damit er diesen Header überhaupt zu Gesicht bekommt. Sollte der allererste Besuch von „www.unbekannt.de“ über eine Leitung laufen die ein Angreifer kontrolliert, und dieser Angreifer verhindert dass der HSTS-Header den Browser erreicht, dann hilft es natürlich nichts gegen diesen Man-in-the-Middle Angriff. HSTS hilft nur bei zukünftigen Besuchen, nachdem einmal ein sicherer Aufruf per HTTPS stattgefunden hat. Oder aber man trägt seine Seite in die preloaded HSTS-Liste von Chrome und Firefox ein, dann ist HSTS auch vor dem allerersten Besuch für die Domain aktiviert und sie wird automatisch per HTTPS aufgerufen. Schön wäre es natürlich auch wenn man diese HSTS-Einstellung im DNS-System hinterlegen könnte, dann müßte aber natürlich auch DNSSEC zum Einsatz kommen damit der Angreifer nicht auch diesen DNS-Query manipulieren kann.
Meine Analyse der Alexa Top 1M
Der Header ist noch relativ jung (19. November 2012: RFC 6797), und mich interessierte wie weit verbreitet dieser Header aktuell ist. Also habe ich mir die Alexa Top 1 Million Websites Liste geschnappt, einen kleinen Parser geschrieben und die Domains analysiert.
Herausgekommen ist dabei folgendes:
44,4% der Domains sind per HTTPS erreichbar. Von diesen HTTPS-fähigen Domains liefern 0,43% den neuen Header aus mit max-age>0, finde ich verdammt wenig ehrlich gesagt. Nagut, mein Webserver ist auch per HTTPS erreichbar und liefert den Header nicht aus. Dafür tut es aber seit kurzer Zeit mein Arbeitgeber mail.de, sogar inklusive „includeSubDomains“ 😉
Interessant ist auch was einige mit der Angabe „max-age“ anfangen. Normalerweise ist es sinnvoll diesen Wert so hoch wie möglich zu setzen, damit der Besucher auch einige Pausen, in denen die Seite nicht besucht wird, überbrücken kann und nicht direkt wieder „zurückfällt“ auf das alte unverschlüsselte Verhalten. Deshalb ist es sinnvoll dort z.B. einen Monat oder besser ein Jahr zu nehmen. Nicht zu verstehen ist deshalb warum einige Domains einen Wert von 1, 5 oder 60 Sekunden angeben. Der Browser merkt sich also nur sehr kurz dass diese Domain bitte in Zukunft nur noch per HTTPS zu kontaktieren ist, der Schutz ist dadurch faktisch nicht gegeben. Eventuell sind es auch nur Tests.
Eine Sonderstellung nimmt der Wert „max-age=0“ ein, der nicht etwa „unendlich“ bedeutet sondern dem Browser mitteilt er soll die gemerkte Einstellung für die Domain sofort verlernen. Das ist sinnvoll für den Fall dass die Domain in Zukunft (auch) wieder unverschlüsselt aufgerufen werden können soll. Der bekannteste Vertreter in den Top 100.000, der „max-age=0“ ausliefert, ist Twitter mit der Domain t.co
Den Quelltext des kleinen Parsers gibt es auf GitHub, wer also in einem Jahr eine weitere Analyse machen möchte darf das gern tun. Auch gibt es die Ergebnisse als CSV zum Download. Die Grafik oben und noch einige weitere Grafiken und Zahlen befinden sich auf der kleinen Webseite http://hstscheck.phpgangsta.de.
Vergleich mit einer Studie von 2012
Bei der Recherche habe ich eine Studie (PDF) zur Verbreitung von HSTS gefunden von Oktober 2012, also noch bevor der Standard verabschiedet wurde. Zu dieser Zeit beherrschten aber bereits die modernen Browser dieses neue Feature. Interessant dabei ist dass die Zahlen in Gegensatz zu meinen aktuellen Zahlen teilweise sehr unterschiedlich sind. Beispielsweise waren Ende 2012 laut dieser Studie nur ca. 10% der Webseiten per HTTPS erreichbar, bei meiner Analyse komme ich auf 44%. Ich glaube kaum dass sich innerhalb eines Jahres diese Zahl so gravierend geändert hat, der einzige Unterschied den ich anhand des PDFs feststellen konnte ist dass selbstsignierte Zertifikate in der Studie „nicht berücksichtigt“ wurden. Sind in den 1 Millionen wichtigsten Webseiten so viele selbstsignierte/ungültige Zertifikate unterwegs?
Beim prozentualen Anteil der per HSTS gesicherten Domains sind es in der Studie 0,41% und in meiner Analyse 0,43%, die Verbreitung ist also nur sehr leicht gestiegen innerhalb eines Jahres.
Fazit
Noch relativ wenige große Webseiten, die HTTPS anbieten, nutzen dieses Sicherheitsfeature. Neben dem Sicherheitsgewinn gibt es auch einen kleinen Performancegewinn, denn der unverschlüsselte Request, der mit einem Redirect auf die verschlüsselte Webseite beantwortet wird, entfällt, man spart einige Millisekunden beim Aufruf der Seite.
Nutzen wir mittlerweile für immer mehr Projekte. Kleinere Projekte laufen bereits mit einer max-age von 18 Monaten. Das größte wird derzeit mit einer kurzen Dauer von 10 Minuten getestet. Falls es keine Probleme gibt (IE6…) werden wir das nächste Woche auch auf 18 Monate stellen.
Der Header tut keinem weh, und wenn man sowieso bereits per https erreichbar ist, ist er ein deutlicher Zusatzgewinn an Sicherheit mit kleinstmöglichem Aufwand. Netter Nebeneffekt: man erspart sich jede Menge 301er im Log 😉
Marcus Schwarz
28 Nov 13 at 13:32
LOL und mein Chef hat mich letzten Monat gezwungen unseren HTTPS auszuhebeln. Jeder der HTTPS eingibt wird auch HTTP umgeleitet.
Und warum haben wir überhaupt HTTPS? Weil es Facebook für eine kleine Seite verlangt.
*Kopfschüttel*
T-Rex
11 Dez 13 at 09:39
Dabei wäre es über einen der vielen bekannten CDN Anbieter relativ einfach umsetzbar.
Soweit ich weiß unterstützt es mein CDN Anbieter.
Ich werde auch definitiv HSTS bzw explizit HTTPS nutzen.
Es schadet nie, die Verbindung zu verschlüsseln =)
Daniel Ruf
30 Dez 13 at 17:49
[…] HSTS – HTTP Strict Transport Security: Hast’s schon? […]
HSTS – Was es ist, wie es funktioniert und wie man es in Apache einrichtet | pregos blog
31 Jan 14 at 20:16