Zum Hauptinhalt Zur Navigation

HTTP-Header: Webseiten vor Spectre schützen

Eine Reihe neuer HTTP -Header ermöglicht es, Webseiten besser voneinander abzuschotten und damit Seitenkanalangriffe wie Spectre zu verhindern.
/ Hanno Böck
13 Kommentare News folgen (öffnet im neuen Fenster)
Neue HTTP-Header sorgen dafür, dass Webprozesse voneinander abgeschottet werden können. Das verhindert Spectre-Angriffe. (Bild: pxhere)
Neue HTTP-Header sorgen dafür, dass Webprozesse voneinander abgeschottet werden können. Das verhindert Spectre-Angriffe. Bild: pxhere / CC0 1.0

Um Webseiten vor Angriffen wie Spectre zu schützen, müssen sie besser voneinander abgeschottet werden. Doch das Web ist bisher so gebaut, dass Webseiten auf verschiedene Weise miteinander interagieren und externe Inhalte einbinden können. Um hier Lücken zu schließen, gibt es eine Reihe von neuen HTTP-Headern.

Die Sicherheitslücke Spectre, die im Januar 2018 bekanntwurde, hat scheinbare Gewissheiten in Sachen IT-Sicherheit erschüttert und gezeigt: Über Seitenkanäle wie die Geschwindigkeit von Cache-Zugriffen lässt sich unberechtigt Speicher auslesen. Seitdem wurden mehrfach Varianten dieser Angriffe entdeckt und viele der entwickelten Gegenmaßnahmen erwiesen sich als unzureichend.

Spectre-Lücken auch in Webbrowsern angreifbar

Ein Risiko durch Spectre und dessen Varianten besteht auch in Webbrowsern, da solche Lücken mittels Javascript angegriffen werden können. Eine großflächige Ausnutzung fand bislang nicht statt, da die Angriffe kompliziert sind, doch ein Risiko bleibt. Google hat zuletzt einen Proof of Concept präsentiert , mit dem ein Datenleck via Spectre zwischen Webseiten gezeigt wurde.

In einer ersten Reaktion hatten Browser nach der Entdeckung von Spectre verschiedene, als gefährlich eingeschätzte Features deaktiviert oder eingeschränkt. Shared-Array-Buffer-Objekte(öffnet im neuen Fenster) , die einen schnellen Direktzugriff auf Speicher ermöglichen, wurden deaktiviert, verschiedene Timer-Funktionen wurden in ihrer Genauigkeit eingeschränkt.

Inzwischen gibt es ausgefeiltere Schutzmaßnahmen, die jedoch teilweise Änderungen bei der Webentwicklung erfordern. Wer die Maßnahmen alle umsetzt, kann den Zugriff auf die deaktivierten Funktionen wieder freischalten.

Webseiten werden in eigene Prozesse eingesperrt

Diese Schutzmaßnahmen zielen darauf ab, Webseiten voneinander zu isolieren. Bereits vor der Entdeckung von Spectre arbeiteten Entwickler von Google Chrome an einem Feature namens Site Isolation . Das sah vor, dass jede Webseite in einem abgeschotteten Render-Prozess läuft. Für Google war das ein Glücksfall: Das Feature eignete sich als Schutz vor Spectre und die Einführung wurde beschleunigt.

Reklame

Hacking & Security: Das umfassende Hacking-Handbuch mit über 1.000 Seiten Profiwissen. 3., aktualisierte Auflage des IT-Standardwerks (Gebundene Ausgabe)

Jetzt bestellen bei Amazon (öffnet im neuen Fenster)

Mozilla hat nachgezogen und mit Project Fission ebenfalls eine derartige Seitenisolierung implementiert . Diese Funktion ist bisher nicht standardmäßig aktiviert.

Um die Seitenisolierung zu perfektionieren, muss gewährleistet sein, dass eine Webseite nicht die Inhalte einer anderen einbinden kann. Genau das ist aber nicht einfach. Im Web ist es standardmäßig vorgesehen, Bilder, Javascript- oder CSS-Dateien von anderen Seiten einzubinden.

Blockieren von Ladevorgängen anderer Hosts

Ein zentrales Konzept der Websicherheit ist die Same-Origin-Policy. Diese besagt, dass eine Webseite auf einem Hostnamen nicht die Inhalte eines anderen Hostnamens mittels Javascript auslesen kann. Ebenso blockiert die Same-Origin-Policy Zugriffe zwischen verschiedenen Ports und Protokollen. Das heißt: Eine bösartige Webseite kann den Inhalt eines gleichzeitig geöffneten Webmail-Systems nicht auslesen.

Trotz Same-Origin-Policy gibt es eine ganze Reihe von Interaktionen, die zwischen Webseiten auf verschiedenen Hostnamen möglich sind. Das einfachste Beispiel ist das Laden von Ressourcen wie Bildern, CSS-Dateien oder Javascript-Dateien.

Nehmen wir zwei Webseiten, die unter example.com und example.org betrieben werden. Wenn unter example.org/test.jpg ein Bild liegt, kann die Webseite example.com dieses Bild anzeigen lassen. Das Bild kann angezeigt werden, auf example.com laufender Javascript-Code darf es aber wegen der Same-Origin-Policy nicht auslesen. Denn es kann sich um ein Bild handeln, das nicht öffentlich abrufbar ist und nur nach einem Login angezeigt wird.

Da das Bild vom Browser auf example.com angezeigt wird, ist es fast zwangsweise so, dass der Inhalt des Bildes in demselben Browserprozess läuft wie der Javascript-Code von example.com . Läuft auf example.com ein Spectre-Exploit, könnte damit das Bild ausgelesen werden.

Hier setzt ein neuer Header namens Cross-Origin-Resource-Policy(öffnet im neuen Fenster) (abgekürzt CORP) an. Dieser verhindert, dass andere Webseiten die eigenen Ressourcen einbinden.

Setzt man den Header auf same-origin bedeutet dies, entsprechende Inhalte dürfen nur von der eigenen Origin eingebunden werden. Im oben erwähnten Beispiel kann example.org für alle Inhalte den Header Cross-Origin-Resource-Policy: same-origin setzen und damit verhindern, dass dort abgelegte Bilder auf example.com angezeigt werden. Analog dasselbe gilt für andere externe Ressourcen wie CSS- oder Javascript-Dateien.

Reklame

Hacking & Security: Das umfassende Hacking-Handbuch mit über 1.000 Seiten Profiwissen. 3., aktualisierte Auflage des IT-Standardwerks (Gebundene Ausgabe)

Jetzt bestellen bei Amazon (öffnet im neuen Fenster)

Etwas laxer ist die Einstellung same-site , hier können Inhalte von anderen Subdomains derselben Hauptdomain eingebunden werden. Mit cross-origin erlaubt man explizit allen das Einbinden von Inhalten. Das explizite Erlauben ist die Standardeinstellung, sinnvoll wird diese Option in Kombination mit einem weiteren Feature.

Nur explizit erlaubte Inhalte mit COEP

Das Gegenstück zu Cross-Origin-Resource-Policy ist der Header Cross-Origin-Embedder-Policy(öffnet im neuen Fenster) (abgekürzt COEP). Damit kann festgelegt werden, dass eine Webseite nur solche Inhalte von anderen Webseiten einbindet, die dies explizit erlauben. Der Header kann den Wert require-corp enthalten, damit dürfen nur Inhalte von anderen Origins eingebunden werden, die ihrerseits via CORP das Laden gestatten. Die andere mögliche Einstellung ist unsafe-none , was dem bisherigen Standard entspricht.

Betrachten wir wieder ein Beispiel: Die Webseite example.com setzt den Header Cross-Origin-Embedder-Policy und versucht anschließend, ein Bild von example.org einzubinden. Solange example.org keine besonderen Header setzt, die das Einbinden explizit erlauben, wird der Ladevorgang blockiert.

Damit der Ladevorgang funktioniert, muss die Seite example.org explizit das Einbinden ihrer Bilder erlauben. Dafür sorgt der Header Cross-Origin-Resource-Policy: cross-origin . Nun kann example.com erfolgreich Bilder von example.org einbinden.

Eine Variante, das Laden zu erlauben, ist der Mechanismus Cross-Origin-Resource-Sharing (CORS) mit dem Header Access-Control-Allow-Origin . Dafür muss man beim Laden im entsprechenden HTML-Tag das Attribut crossorigin angeben. CORS gibt es schon länger und soll hier nicht im Detail erklärt werden. Der Vorteil dieser Methode ist, dass viele Webseiten CORS bereits unterstützen.

Interaktion zwischen öffnenden und geöffneten Fenstern blockieren

Eine weitere Situation, in der Webseiten trotz Same-Origin-Policy eingeschränkt miteinander interagieren können, sind Popups. Öffnet eine Seite ein Popup einer anderen Webseite, kann die öffnende Webseite auf das Seitenobjekt zugreifen. Damit kann beispielsweise das Popup nach einiger Zeit auf eine andere Webseite weitergeleitet werden.

Reklame

Hacking & Security: Das umfassende Hacking-Handbuch mit über 1.000 Seiten Profiwissen. 3., aktualisierte Auflage des IT-Standardwerks (Gebundene Ausgabe)

Jetzt bestellen bei Amazon (öffnet im neuen Fenster)

Ähnliches funktioniert in die andere Richtung. Eine in einem Popup geöffnete Webseite kann mittels Javascript auf das Objekt window.opener zugreifen und den öffnenden Browsertab auf eine andere Webseite weiterleiten. Über diese Zugriffe auf das Fenster-Objekt sind Seitenkanalangriffe möglich, die als XSLeaks(öffnet im neuen Fenster) bekannt sind.

Solche Interaktionen zwischen öffnenden und geöffneten Fenstern hinweg werden nur selten benötigt. Mit dem Header Cross-Origin-Opener-Policy(öffnet im neuen Fenster) lässt sich dies unterbinden. Diese kann auf den Wert same-origin gesetzt werden.

Neben diesen drei neuen Headern gibt es noch weitere, bereits länger unterstützte Header, die in Sachen Seitenisolierung sinnvoll sind.

Content-Sniffing abschalten ist generell empfehlenswert

Der Header X-Content-Type-Options: nosniff deaktiviert in Browsern das Content-Sniffing. Das verhindert manche Formen von Cross-Site-Scripting-Angriffen, es verbessert aber auch die Seitenisolierung.

Aus historischen Gründen ignorieren Browser manchmal den Inhaltstyp im Header Content-Type einer HTTP-Ressource. Beispielsweise werden Javascript- oder CSS-Dateien, die mit dem Typ text/plain ausgeliefert werden, akzeptiert. Der Browser versucht, den Dateityp anhand ihres Inhaltes zu erraten. Setzt man den nosniff-Header, dann wird derartiges Akzeptieren von falschen Dateitypen unterbunden.

Diesen Header gab es schon lange, bevor Spectre-Angriffe bekanntwurden, er bietet aber auch hier einen zusätzlichen Schutz. Google hat in der Chrome-Architektur ein Konzept eingeführt, das sich Cross-Origin Resource Blocking(öffnet im neuen Fenster) (CORB) nennt. Firefox arbeitet an einer Variante, die dort als CORB++ bezeichnet wird(öffnet im neuen Fenster) .

Ladevorgänge frühzeitig blockieren

Die Idee dabei: Wenn eine Webseite versucht, fehlerhaft Inhalte einer anderen Seite einzubinden, wird dies blockiert, bevor der Inhalt überhaupt im Renderprozess einer Seite landet. Beispielsweise könnte eine Webseite versuchen, den HTML-Inhalt einer anderen Seite als CSS-Datei einzubinden. Das würde beim Parsen Fehler verursachen, doch der Inhalt der HTML-Datei wäre im Speicherbereich der fremden Webseite und könnte durch Spectre auslesbar sein.

Um das zu verhindern, sollen derartige Ladevorgänge bereits blockiert werden, bevor sie im Renderprozess einer Webseite ankommen. Wenn der Nosniff-Header gesetzt ist, kann der Browser bereits beim Prüfen des Inhaltstyps das Laden verwerfen. Ansonsten muss der Browser den Inhalt anschauen und entscheiden, ob es sich um einen validen Ladevorgang handelt. Der Nosniff-Header sorgt dafür, dass der Browser einen Ladevorgang mit fehlerhaften Inhaltstypen sofort abbrechen kann.

Den Nosniff-Header zu setzen, ist praktisch immer die richtige Wahl. Die einzig mögliche negative Auswirkung ist, dass Inhalte mit einem falschen Content-Type nicht mehr geladen werden können. In dem Fall sollte man den Webserver so konfigurieren, dass er Dateien mit dem korrekten Content-Type ausliefert.

Reklame

Hacking & Security: Das umfassende Hacking-Handbuch mit über 1.000 Seiten Profiwissen. 3., aktualisierte Auflage des IT-Standardwerks (Gebundene Ausgabe)

Jetzt bestellen bei Amazon (öffnet im neuen Fenster)

Frames und Iframes

Eine weitere Möglichkeit, mit der Webseiten miteinander interagieren, sind Frames und Iframes. Diese haben schon zu anderen Angriffsformen geführt, die bekannteste ist das Clickjacking. Mit dem Header X-Frame-Options kann eine Webseite unterbinden, dass sie von anderen Seiten in einem Frame geladen wird. Dieser Header kann entweder den Wert deny (Laden in Frames generell untersagt) oder sameorigin (Laden nur von derselben Origin erlaubt) haben.

Alternativ gibt es die Möglichkeit, ein ähnliches Verhalten über die Direktive frame-ancestors mittels des Content-Security-Poliy-Headers zu erreichen(öffnet im neuen Fenster) .

Isolierung für manche Javascript-Features nötig

Die neuen und alten Header sind vergleichsweise komplex. Am einfachsten haben es simple Webseiten, die keine Frames nutzen und keine externen Ressourcen einbinden oder für andere bereitstellen. Sie können die folgende Kombination an Headern setzen und sich damit abschotten:

        
Cross-Origin-Resource-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
X-Content-Type-Options: nosniff
X-Frame-Options: deny

Letztendlich ist dies die Einstellung, welche die meisten Webseiten anstreben sollten. Alle externen Inhalte müssen dann explizit das Einbinden erlauben. Wer die drei neuen Header mit sicheren Optionen konfiguriert hat, erhält Zugriff auf die Javascript-Features, die nach der Entdeckung von Spectre abgeschaltet wurden.

In Javascript kann die Eigenschaft crossOriginIsolated(öffnet im neuen Fenster) geprüft werden, die bestätigt, dass Shared-Array-Buffer und hochauflösende Timer wieder genutzt werden können.

Implementierung hat noch Macken

Bei den Recherchen ist uns aufgefallen, dass die Implementierungen der neuen HTTP-Header noch Fehler haben. In Firefox wurden Ladevorgänge einer Seite mit COEP, die eigentlich explizit via CORP erlaubt waren, in manchen Fällen blockiert(öffnet im neuen Fenster) . Der Grund dafür war, dass die Daten aus dem Cache gelesen wurden und dieser die CORP-Eigenschaft nicht gespeichert hatte. Auch stellten wir fest, dass ein RSS-Feed auf einer Seite mit CORP von Thunderbird nicht mehr geladen werden konnte(öffnet im neuen Fenster) . Beide Probleme haben wir an Mozilla gemeldet.

Solche Bugs werden sicher seltener, wenn mehr Personen die neuen Header einsetzen und die Implementierungen ausgereifter werden. Vorerst sollte mit der ein oder anderen Macke gerechnet werden.

Hanno Böck ist Golem-Redakteur für die Themen IT-Sicherheit und Kryptographie. Bei der Golem Akademie gibt Hanno den Workshop " IT-Sicherheit für Webentwickler ". In dem zweitägigen Onlineseminar führen die Teilnehmer Angriffe auf reale Webapplikationen praktisch durch und analysieren, wie sich solche Schwachstellen schließen lassen.


Relevante Themen