Why TLS is crappy by Design

Jeder der das Internet benutzt, der nutzt auch TLS, besser bekannt unter dem alten Namen SSL. TLS sorgt dafür, dass eine HTTP Verbindung zwischen dem Client und einem Server verschlüsselt ist. Alle Daten die ich an die Website übermittel und vice versa können nicht von Dritten mitgelesen werden. Insbesondere nach den Enthüllungen von Edward Snowden sollte jeder Betreiber einer Website TLS standardmäßig zur Verfügung stellen.

TLS selbst gilt als (weitgehend) sicher. Daran möchte ich auch nichts rütteln.Was jedoch einerseits ein Sicherheits Feature ist, ist gleichzeitig auch ein großes Problem. Wenn zwischen Client und Server erstmal eine Verbindung aufgebaut wurde, dann werden sämtliche Inhalte verschlüsselt übertragen. Sobald eine TLS Verbindung einmal aufgebaut ist, dann ist es unmöglich zu unterscheiden, für welche Domain das eingehende TLS Paket ist. Wenn man auf einem Server unter der gleichen IP Adresse mehrere Domains betreibt, z.B. foo.example.com und bar.example.com, und beide (Sub-)Domains verschiedene Zertifikate mit unterschiedlichen Schlüsseln zur Verschlüsselung der Verbindung verwenden, dann kann der Server später nicht unterscheiden, ob ein eingehendes verschlüsseltes Paket für foo.example.com oder für bar.example.com bestimmt ist.

Grundsätzlich ist dieses Verhalten gut, da ein Angreifer nicht sehen kann, welche URIs der Client abrufen möchte. Es führt aber auch zu gewaltigen Problemen:

Wenn man eine Reihe von Servern betreibt, auf denen eine Webapplication in mehreren Instanzen läuft und Kunden über my-instance.awesome-company.com zugreifen, dann ist es wünschenswert einen Loadbalancer zu betreiben, der alle Anfragen an *.awesome-company.com entgegen nimmt und jede Anfrage an den Server weiter reicht, auf dem die angeforderte Instanz betrieben wird (eine Aufteilung der Kunden auf isolierte Instanzen ist aus Datenschutz Gründen wünschenswert oder sogar erforderlich). Durch HTTPS wird das leider unmöglich: Aus einem verschlüsselten Paket kann man später nicht mehr feststellen, an welche Instanz dieses weitergeleitet werden muss.

Bisher ist die einzige Möglichkeit das Problem zu umgehen der Einsatz eines TLS Reverse Proxies. Hier baut der Client eine verschlüsselte Verbindung zum Loadbalancer auf. Dieser entschlüsselt die Nachricht und kann dann anhand des HTTP Headers erkennen, für welche Instanz das Paket gedacht ist. Der Loadbalancer schickt dass Paket dann über eine neue Verbindung entweder im Klartext oder über eine neue TLS Verbindung an den Instanz Server weiter. Umgekehrt schickt der Instanz Server seine Antwort an den Reverse Proxy, der diese dann an den Client weitergibt. Dieses Model hat zwei nennenswerte Probleme: Zum einen bietet die TLS Verbindung hier keine echte Ende-zu-Ende Verschlüsselung. Daten können auf dem Load Balancer entschlüsselt und ggf. manipuliert oder von Dritten gelesen werden. Zum anderen müssen die Daten vom Loadbalancer zum Instanz Server neu verschlüsselt werden. Das kostet zusätzliche Ressourcen und damit zusätzliches Geld. Es kommt daher nicht selten vor, dass die Verbindung vom Loadbalancer zu den Background Servern nicht verschlüsselt ist.

Eine mögliche Lösung wäre die Erweiterung von TLS. Dazu in einem späteren Post mehr.