Böswillige Zwischenhändler mit HTTPS und HTTP Strict Transport Security verwirren

Angesichts der Menge an personenbezogenen Daten, die durch das Internet fließen, ist Verschlüsselung kein Thema, das wir leichtfertig ignorieren können oder sollten. Moderne Browser bieten mehrere Mechanismen, mit denen Sie dafür sorgen können, dass die Daten Ihrer Nutzer während der Übertragung sicher sind: Sichere Cookies und Strict Transport Security sind zwei der wichtigsten. Sie können damit Ihre Nutzer nahtlos schützen, ihre Verbindungen auf HTTPS umstellen und dafür sorgen, dass Nutzerdaten niemals unverschlüsselt gesendet werden.

Was hat das mit mir zu tun? Berücksichtigen Sie Folgendes:

Die Bereitstellung einer Webseite über eine unverschlüsselte HTTP-Verbindung ist in etwa so, als würden Sie einen ungeöffneten Umschlag der ersten Person auf der Straße geben, die in Richtung Post geht. Mit etwas Glück bringt sie die Sendung selbst bis zum Ziel oder übergibt sie der nächsten Person, die sie sieht und in die richtige Richtung unterwegs ist. Diese Person könnte das Gleiche tun und so weiter.

Die meisten Fremden in dieser spontanen Kette sind vertrauenswürdig und würden niemals in Ihren offenen Brief schauen oder ihn ändern. Je öfter der Brief den Besitzer wechselt, desto mehr Personen haben jedoch Zugriff auf den von Ihnen gesendeten Brief. Letztendlich ist es sehr wahrscheinlich, dass der beabsichtigte Empfänger Ihres Briefes etwas per Post erhält. Ob es sich dabei jedoch um das Gleiche handelt, was Sie ursprünglich übergeben haben, ist eine offene Frage. Vielleicht hätten Sie den Umschlag versiegeln sollen…

Zwischenhändler

Zum Guten oder Schlechten: Große Teile des Internets beruhen auf der Vertrauenswürdigkeit von Fremden. Die Server sind nicht direkt miteinander verbunden, sondern geben Anfragen und Antworten in einem riesigen Telefonspiel von Router zu Router weiter.

Mit Traceroute können Sie diese Hops in Aktion sehen. Der Pfad von meinem Computer zu HTML5Rocks sieht in etwa so aus:

$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
 1  router1-lon.linode.com (212.111.33.229)  0.453 ms
 2  212.111.33.233 (212.111.33.233)  1.067 ms
 3  217.20.44.194 (217.20.44.194)  0.704 ms
 4  google1.lonap.net (193.203.5.136)  0.804 ms
 5  209.85.255.76 (209.85.255.76)  0.925 ms
 6  209.85.253.94 (209.85.253.94)  1.226 ms
 7  209.85.240.28 (209.85.240.28)  48.714 ms
 8  216.239.47.12 (216.239.47.12)  22.575 ms
 9  209.85.241.193 (209.85.241.193)  36.033 ms
10  72.14.233.180 (72.14.233.180)  43.222 ms
11  72.14.233.170 (72.14.233.170)  43.242 ms
12  *
13  lb-in-f102.1e100.net (173.194.71.102)  44.523 ms

13 Hopps sind eigentlich nicht schlecht. Wenn ich jedoch Anfragen per HTTP sende, hat jeder dieser Zwischenrouter vollen Zugriff auf meine Anfragen und die Antworten der Server. Alle Daten werden als unverschlüsselter Klartext übertragen und jeder dieser Intermediäre könnte als Man-in-the-Middle agieren, meine Daten lesen oder sie sogar während der Übertragung manipulieren.

Schlimmer noch: Diese Art der Datenabfangung ist praktisch nicht nachweisbar. Eine böswillig manipulierte HTTP-Antwort sieht genau wie eine gültige Antwort aus, da es keinen Mechanismus gibt, mit dem Sie sicherstellen können, dass die empfangenen Daten genau die gesendeten Daten sind. Wenn jemand mein Internet aus Spaß auf den Kopf stellt, habe ich mehr oder weniger keine Chance.

Ist das eine sichere Leitung?

Der Wechsel von unverschlüsselten HTTP- zu sicheren HTTPS-Verbindungen ist die beste Verteidigung gegen Middlemen. Bei HTTPS-Verbindungen wird der gesamte Kanal Ende-zu-Ende verschlüsselt, bevor Daten gesendet werden. Dadurch können Maschinen zwischen Ihnen und Ihrem Ziel keine Daten während der Übertragung lesen oder ändern.

Die Chrome-Omnibox enthält viele Details zum Status einer Verbindung.
Die Omnibox von Chrome liefert ziemlich viele Details zum Status einer Verbindung.

Die Sicherheit von HTTPS basiert auf dem Konzept öffentlicher und privater kryptografischer Schlüssel. Eine ausführliche Erläuterung der Details würde (glücklicherweise) den Rahmen dieses Artikels sprengen. Die Grundvoraussetzung ist jedoch recht einfach: Daten, die mit einem bestimmten öffentlichen Schlüssel verschlüsselt wurden, können nur mit dem entsprechenden privaten Schlüssel entschlüsselt werden. Wenn ein Browser einen HTTPS-Handshake startet, um einen sicheren Kanal zu erstellen, stellt der Server ein Zertifikat bereit, das dem Browser alle Informationen zur Verfügung stellt, die er benötigt, um seine Identität zu überprüfen, indem er prüft, ob der Server den richtigen privaten Schlüssel hat. Die gesamte Kommunikation ab diesem Punkt wird so verschlüsselt, dass nachgewiesen werden kann, dass Anfragen an den authentifizierten Server gesendet und Antworten von ihm empfangen werden.

HTTPS bietet Ihnen daher eine gewisse Sicherheit, dass Sie mit dem Server kommunizieren, mit dem Sie glauben, zu kommunizieren, und dass niemand anderes zuhört oder Bits auf der Leitung manipuliert. Diese Art der Verschlüsselung ist eine absolute Voraussetzung für die Sicherheit im Web. Wenn Ihre Anwendung derzeit nicht über HTTPS bereitgestellt wird, ist sie anfällig für Angriffe. Problem beheben. Ars Technica hat einen tollen Leitfaden zum kostenlosen Erhalten und Installieren eines Zertifikats, den ich Ihnen für technische Details empfehlen würde. Die Konfiguration unterscheidet sich von Anbieter zu Anbieter und von Server zu Server, aber der Prozess für die Zertifikatsanfrage ist überall gleich.

Standardmäßig sicher

Nachdem Sie ein Zertifikat angefordert und installiert haben, sollten Sie dafür sorgen, dass Ihre Nutzer von Ihrer harten Arbeit profitieren: Migrieren Sie Ihre bestehenden Nutzer transparent über die magische HTTP-Weiterleitung zu HTTPS-Verbindungen und sorgen Sie dafür, dass Cookies nur über sichere Verbindungen gesendet werden.

Bitte hier entlang.

Wenn ein Nutzer http://example.com/ aufruft, leite ihn zu https://example.com/ weiter, indem du eine 301 Moved Permanently-Antwort mit einem entsprechenden Location-Header sendest:

$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/

Sie können diese Art der Weiterleitung ganz einfach auf Servern wie Apache oder Nginx einrichten. Eine Nginx-Konfiguration, die von http://example.com/ zu https://example.com/ weiterleitet, sieht beispielsweise so aus:

server {
    listen [YOUR IP ADDRESS HERE]:80;
    server_name example.com www.example.com;
    location "/" {
        rewrite ^(.*) https://www.example.com$1 permanent;
    }
}

Mithilfe von Cookies können wir Nutzern eine nahtlose Anmeldung über das zustandslose HTTP-Protokoll ermöglichen. In Cookies gespeicherte Daten, einschließlich vertraulicher Informationen wie Sitzungs-IDs, werden mit jeder Anfrage gesendet. So kann der Server nachvollziehen, auf welchen Nutzer er gerade reagiert. Nachdem wir sichergestellt haben, dass Nutzer unsere Website über HTTPS aufrufen, sollten wir auch dafür sorgen, dass die in Cookies gespeicherten sensiblen Daten immer nur über eine sichere Verbindung übertragen und nie unverschlüsselt gesendet werden.

Das Setzen eines Cookies umfasst in der Regel einen HTTP-Header, der in etwa so aussieht:

set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT

Sie können den Browser anweisen, die Verwendung des Cookies zur Sicherung von Sitzungen einzuschränken, indem Sie ein einzelnes Keyword anhängen:

Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure

Cookies, die mit dem Keyword secure festgelegt werden, werden niemals über HTTP gesendet.

Offenes Fenster schließen

Bei der transparenten Weiterleitung zu HTTPS verwenden Ihre Nutzer die meiste Zeit, in der sie auf Ihrer Website sind, eine sichere Verbindung. Es bleibt jedoch ein kleines Zeitfenster für Angriffe offen: Die ursprüngliche HTTP-Verbindung ist weit offen und anfällig für SSL-Entfernung und ähnliche Angriffe. Da ein Man-in-the-Middle-Angriff Zugriff auf die ursprüngliche HTTP-Anfrage hat, kann er als Proxy zwischen Ihnen und dem Server fungieren und Sie unabhängig von den Absichten des Servers in einer unsicheren HTTP-Verbindung halten.

Sie können das Risiko dieser Art von Angriff verringern, indem Sie den Browser auffordern, HTTP Strict Transport Security (HSTS) durchzusetzen. Wenn Sie den HTTP-Header Strict-Transport-Security senden, wird der Browser angewiesen, die HTTP-zu-HTTPS-Weiterleitung clientseitig durchzuführen, ohne das Netzwerk zu berühren. Dies ist auch sehr vorteilhaft für die Leistung, da die beste Anfrage diejenige ist, die nicht gestellt werden muss:

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Browser, die diesen Header unterstützen (derzeit Firefox, Chrome und Opera: Details auf caniuse), notieren sich, dass für diese Website nur der Zugriff über HTTPS angefordert wurde. Das bedeutet, dass Nutzer unabhängig davon, wie sie die Website aufrufen, sie über HTTPS besuchen. Auch wenn sie http://example.com/ in den Browser eingibt, wird sie auf HTTPS weitergeleitet, ohne dass eine HTTP-Verbindung hergestellt wird. Noch besser: Wenn der Browser ein ungültiges Zertifikat erkennt (potenzieller Versuch, die Identität Ihres Servers zu fälschen), dürfen Nutzer nicht über HTTP fortfahren. Es ist also alles oder nichts, was hervorragend ist.

Der Browser lässt den HSTS-Status des Servers nach max-age Sekunden ablaufen (in diesem Beispiel etwa ein Monat). Legen Sie einen relativ hohen Wert fest.

Sie können auch dafür sorgen, dass alle Subdomains eines Ursprungs geschützt sind, indem Sie dem Header die Anweisung includeSubDomains hinzufügen:

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Sicher unterwegs

HTTPS ist die einzige Möglichkeit, sich auch nur annähernd sicher zu sein, dass die von Ihnen gesendeten Daten intakt beim beabsichtigten Empfänger ankommen. Sie sollten jetzt sichere Verbindungen für Ihre Websites und Anwendungen einrichten. Das ist ein ziemlich einfacher Vorgang, der dazu beiträgt, die Daten Ihrer Kunden zu schützen. Sobald Sie einen verschlüsselten Kanal eingerichtet haben, sollten Sie Nutzer unabhängig davon, wie sie auf Ihre Website gelangt sind, transparent auf diese sichere Verbindung weiterleiten. Senden Sie dazu eine 301-HTTP-Antwort. Achten Sie dann darauf, dass für alle sensiblen Sitzungsinformationen Ihrer Nutzer nur diese sichere Verbindung verwendet wird. Fügen Sie dazu beim Festlegen von Cookies das Schlüsselwort secure hinzu. Nachdem du das alles erledigt hast, solltest du dafür sorgen, dass deine Nutzer nicht versehentlich aus dem Bus fallen: Schütze sie, indem du dafür sorgst, dass ihr Browser das Richtige tut und einen Strict-Transport-Security-Header sendet.

Die Einrichtung von HTTPS ist nicht sehr aufwendig und bietet große Vorteile für Ihre Website und ihre Nutzer. Der Aufwand lohnt sich.

Ressourcen

  • StartSSL bietet kostenlose, domainbestätigte Zertifikate an. Kostenlos ist am besten. Höhere Überprüfungsstufen sind natürlich möglich und preislich attraktiv.
  • SSL-Servertest: Nachdem Sie HTTPS für Ihre Server eingerichtet haben, können Sie mit dem Servertest von SSL Labs prüfen, ob die Einrichtung richtig war. Sie erhalten einen detaillierten Bericht, aus dem hervorgeht, ob alles funktioniert.
  • Der aktuelle Artikel von Ars Technica „Securing your Web Server with SSL/TLS“ (Ihren Webserver mit SSL/TLS schützen) bietet weitere Hintergrundinformationen zur Einrichtung eines Servers.
  • In der HTTP Strict Transport Security-Spezifikation (RFC6797) finden Sie alle technischen Informationen zum Strict-Transport-Security-Header, die Sie benötigen könnten.
  • Sobald Sie wirklich wissen, was Sie tun, können Sie angeben, dass Ihre Website nur über eine bestimmte Gruppe von Zertifikaten erreichbar sein soll. Die IETF arbeitet an einer Funktion, mit der Sie genau das über die Public-Key-Pins-Header-Zeile tun können. Die Entwicklung steht noch am Anfang, ist aber interessant und es lohnt sich, sie im Blick zu behalten.