Warum Sie für leistungsstarke Funktionen eine ursprungsübergreifende Isolierung benötigen

Hier erfahren Sie, warum die ursprungsübergreifende Isolierung erforderlich ist, um leistungsstarke Funktionen wie SharedArrayBuffer, performance.measureUserAgentSpecificMemory() und den hochauflösenden Timer mit besserer Präzision zu verwenden.

Einführung

Im Artikel Website mit COOP und COEP in den Status „cross-origin isolated“ versetzen haben wir erläutert, wie Sie mit COOP und COEP den Status „cross-origin isolated“ erreichen. In diesem Begleitartikel wird erläutert, warum eine ursprungsübergreifende Isolierung erforderlich ist, um leistungsstarke Funktionen im Browser zu aktivieren.

Hintergrund

Das Web basiert auf der Richtlinie für denselben Ursprung. Diese Sicherheitsfunktion schränkt ein, wie Dokumente und Scripts mit Ressourcen aus einem anderen Ursprung interagieren können. Dieses Prinzip schränkt die Möglichkeiten ein, wie Websites auf ursprungsübergreifende Ressourcen zugreifen können. So kann beispielsweise ein Dokument von https://a.example nicht auf Daten zugreifen, die unter https://b.example gehostet werden.

Es gab jedoch in der Vergangenheit einige Ausnahmen von der Richtlinie für denselben Ursprung. Jede Website kann:

  • Ursprungsübergreifende iFrames einbetten
  • Ressourcen aus anderen Quellen wie Bilder oder Skripts einbinden
  • Pop-up-Fenster mit Ursprungsübergreifenden DOM-Referenzen öffnen

Wenn das Web von Grund auf neu entwickelt werden könnte, gäbe es diese Ausnahmen nicht. Leider war es zu diesem Zeitpunkt bereits zu spät, um die Vorteile einer strengen Same-Origin-Richtlinie zu nutzen.

Die Sicherheitsnebenwirkungen einer so laxen Richtlinie für denselben Ursprung wurden auf zwei Arten behoben. Eine Möglichkeit war die Einführung eines neuen Protokolls namens Cross-Origin Resource Sharing (CORS), das sicherstellen soll, dass der Server das Teilen einer Ressource mit einem bestimmten Ursprung zulässt. Die andere Möglichkeit besteht darin, den direkten Skriptzugriff auf ursprungsübergreifende Ressourcen implizit zu entfernen und gleichzeitig die Abwärtskompatibilität beizubehalten. Solche ursprungsübergreifenden Ressourcen werden als „undurchsichtige“ Ressourcen bezeichnet. Das ist beispielsweise der Grund, warum die Bearbeitung der Pixel eines ursprungsübergreifenden Bildes über CanvasRenderingContext2D fehlschlägt, wenn CORS nicht auf das Bild angewendet wird.

Alle diese Richtlinienentscheidungen werden innerhalb einer Browsing-Kontextgruppe getroffen.

Browsing Context Group

Lange Zeit reichte die Kombination aus CORS und undurchsichtigen Ressourcen aus, um Browser sicher zu machen. Manchmal wurden Grenzfälle wie JSON-Sicherheitslücken entdeckt, die gepatcht werden mussten. Insgesamt war das Prinzip, keinen direkten Lesezugriff auf die Rohbytes von Ressourcen mit unterschiedlichen Ursprüngen zuzulassen, jedoch erfolgreich.

Das hat sich mit Spectre geändert. Dadurch können alle Daten, die in dieselbe Browsing-Kontextgruppe wie Ihr Code geladen werden, potenziell gelesen werden. Durch Messen der Zeit, die bestimmte Vorgänge in Anspruch nehmen, können Angreifer den Inhalt der CPU-Caches und damit den Inhalt des Prozessspeichers erraten. Solche Timing-Angriffe sind mit Timern mit niedriger Granularität möglich, die auf der Plattform vorhanden sind. Sie können jedoch mit Timern mit hoher Granularität beschleunigt werden, sowohl explizit (z. B. performance.now()) als auch implizit (z. B. SharedArrayBuffer). Wenn evil.com ein ursprungsübergreifendes Bild einbettet, kann der Angreifer mit einem Spectre-Angriff die zugehörigen Pixeldaten lesen. Schutzmaßnahmen, die auf „Undurchsichtigkeit“ beruhen, sind dann wirkungslos.

Spectr

Im Idealfall sollten alle anfrageübergreifenden Anfragen explizit vom Server geprüft werden, der die Ressource besitzt. Wenn die Überprüfung nicht vom Server des Ressourceninhabers bereitgestellt wird, gelangen die Daten niemals in die Gruppe des Browsing-Kontexts eines böswilligen Akteurs und sind daher vor Spectre-Angriffen geschützt, die von einer Webseite ausgeführt werden könnten. Wir nennen das „ursprungsübergreifend isolierter Status“. Genau darum geht es bei COOP+COEP.

In einem cross-origin-isolierten Zustand gilt die anfragende Website als weniger gefährlich. Dadurch werden leistungsstarke Funktionen wie SharedArrayBuffer, performance.measureUserAgentSpecificMemory() und Timer mit hoher Auflösung mit besserer Präzision freigeschaltet, die andernfalls für Spectre-ähnliche Angriffe verwendet werden könnten. Außerdem wird verhindert, dass document.domain geändert wird.

Cross-Origin-Embedder-Richtlinie

Die Cross-Origin Embedder Policy (COEP) verhindert, dass in einem Dokument Ressourcen unterschiedlicher Herkunft geladen werden, die dem Dokument nicht explizit die Berechtigung (mit CORP oder CORS) erteilen. Mit dieser Funktion können Sie deklarieren, dass ein Dokument solche Ressourcen nicht laden kann.

Funktionsweise von COEP

Um diese Richtlinie zu aktivieren, fügen Sie dem Dokument den folgenden HTTP-Header hinzu:

Cross-Origin-Embedder-Policy: require-corp

COEP akzeptiert nur den Wert require-corp. Dadurch wird die Richtlinie erzwungen, dass das Dokument nur Ressourcen aus demselben Ursprung oder Ressourcen laden kann, die explizit als aus einem anderen Ursprung ladbar gekennzeichnet sind.

Damit Ressourcen von einem anderen Ursprung geladen werden können, müssen sie entweder Cross-Origin Resource Sharing (CORS) oder Cross-Origin Resource Policy (CORP) unterstützen.

Cross-Origin Resource Sharing

Wenn eine ressourcenübergreifende Ressource Cross-Origin Resource Sharing (CORS) unterstützt, können Sie sie mit dem crossorigin-Attribut auf Ihre Webseite laden, ohne dass sie von COEP blockiert wird.

<img src="https://third-party.example.com/image.jpg" crossorigin>

Wenn diese Bildressource beispielsweise mit CORS-Headern bereitgestellt wird, verwenden Sie das Attribut crossorigin, damit für die Anfrage zum Abrufen der Ressource der CORS-Modus verwendet wird. Dadurch wird auch verhindert, dass das Bild geladen wird, wenn keine CORS-Header festgelegt sind.

Ebenso können Sie mit der Methode fetch() Daten aus anderen Quellen abrufen. Das ist unproblematisch, solange der Server mit den richtigen HTTP-Headern antwortet.

Cross-Origin-Ressourcenrichtlinie

Die Cross-Origin Resource Policy (CORP) wurde ursprünglich als Opt-in eingeführt, um Ihre Ressourcen vor dem Laden durch eine andere Herkunft zu schützen. Im Kontext von COEP kann mit CORP die Richtlinie des Ressourceninhabers für die Person angegeben werden, die eine Ressource laden kann.

Der Cross-Origin-Resource-Policy-Header kann drei Werte haben:

Cross-Origin-Resource-Policy: same-site

Ressourcen, die mit same-site gekennzeichnet sind, können nur von derselben Website geladen werden.

Cross-Origin-Resource-Policy: same-origin

Ressourcen, die mit same-origin gekennzeichnet sind, können nur vom selben Ursprung geladen werden.

Cross-Origin-Resource-Policy: cross-origin

Ressourcen, die mit cross-origin gekennzeichnet sind, können von jeder Website geladen werden. Dieser Wert wurde zusammen mit COEP der CORP-Spezifikation hinzugefügt.

Cross-Origin-Opener-Richtlinie

Mit der Cross-Origin-Opener-Policy (COOP) können Sie dafür sorgen, dass ein Fenster der obersten Ebene von anderen Dokumenten isoliert wird, indem diese in eine andere Gruppe von Browserkontexten verschoben werden. So können sie nicht direkt mit dem Fenster der obersten Ebene interagieren. Wenn beispielsweise in einem Dokument mit COOP ein Pop-up geöffnet wird, ist die window.opener-Eigenschaft null. Außerdem gibt die .closed-Property der Referenz des Öffners darauf true zurück.

COOP

Der Cross-Origin-Opener-Policy-Header kann drei Werte haben:

Cross-Origin-Opener-Policy: same-origin

Dokumente, die mit same-origin gekennzeichnet sind, können dieselbe Browsing-Kontextgruppe wie Dokumente mit demselben Ursprung haben, die ebenfalls explizit mit same-origin gekennzeichnet sind.

COOP

Cross-Origin-Opener-Policy: same-origin-allow-popups

Ein Dokument der obersten Ebene mit same-origin-allow-popups behält Verweise auf alle zugehörigen Pop‑ups bei, für die entweder keine COOP festgelegt ist oder die die Isolation durch Festlegen einer COOP von unsafe-none deaktivieren.

COOP

Cross-Origin-Opener-Policy: unsafe-none

unsafe-none ist der Standardwert und ermöglicht, dass das Dokument der Browsing-Kontextgruppe des Öffners hinzugefügt wird, sofern der Öffner selbst keinen COOP-Wert von same-origin hat.

Zusammenfassung

Wenn Sie garantierten Zugriff auf leistungsstarke Funktionen wie SharedArrayBuffer, performance.measureUserAgentSpecificMemory() oder Timer mit hoher Auflösung mit besserer Präzision benötigen, muss in Ihrem Dokument sowohl COEP mit dem Wert require-corp als auch COOP mit dem Wert same-origin verwendet werden. Wenn eines der beiden fehlt, kann der Browser keine ausreichende Isolation garantieren, um diese leistungsstarken Funktionen sicher zu aktivieren. Sie können die Situation Ihrer Seite ermitteln, indem Sie prüfen, ob self.crossOriginIsolated true zurückgibt.

Eine Anleitung zur Implementierung finden Sie unter Website mit COOP und COEP „cross-origin isolated“ machen.

Ressourcen