Zusammenfassung

  • Mit X-Frame-Options: SAMEORIGIN konnte eine Seite fremde Einbettungen untersagen. RFC 7034 hielt 2013 eine Lücke fest: Manche Browser verglichen die geschützte Seite nur mit dem obersten Dokument.
  • Seite A bettet B ein, B bettet wiederum eine geschützte Seite von A ein. Wer nur die Enden prüft, sieht A und A und übersieht B. Die W3C-Regel frame-ancestors verlangte 2016 eine Prüfung jedes übergeordneten Rahmens.

Das fremde Fenster in der Mitte

Eine Seite der Herkunft A enthält einen Rahmen mit einer Seite der Herkunft B. B will darin eine sensible Seite von A zeigen. Diese sensible Seite liefert X-Frame-Options: SAMEORIGIN aus. Der Browser soll sie nur innerhalb derselben Herkunft anzeigen. Prüft er allein den äußersten Rahmen gegen die geschützte Seite, erhält er A auf beiden Seiten und lädt den Inhalt. Unmittelbar um die geschützte Seite liegt aber B. Dieser Zwischenraum blieb ungeprüft.

RFC 7034 vom Oktober 2013 beschrieb genau diese Konstellation. Das Informational-Dokument hielt die damalige Nutzung des Headers und Unterschiede zwischen Browsern fest. Der Header sollte Clickjacking erschweren: Eine Seite kann über eine andere gelegt werden, damit ein Nutzer unbemerkt deren Schaltfläche betätigt. Die Bestellbestätigung im RFC ist ein Beispiel für eine Schutzmaßnahme. Die Kette A/B/A beschreibt einen möglichen Fehlerweg, keinen dokumentierten Angriff auf einen bestimmten Shop.

Eine klare Anweisung, ein zu kurzer Blick

Der Server der gefährdeten Seite sendete den Header in der HTTP-Antwort. DENY verbot jede Einbettung; SAMEORIGIN ließ dieselbe Herkunft zu; ALLOW-FROM nannte eine erlaubte Herkunft. Die Seite bestimmte die Grenze, der Browser setzte sie um. In verschachtelten Fenstern musste die Software allerdings entscheiden, welche Herkunft sie verglich.

Der RFC verzeichnete Unterschiede bei dieser Entscheidung. Manche Implementierungen betrachteten nur das oberste Dokument und die geschützte Seite. Ein fremder Rahmen dazwischen fiel aus der Prüfung. Die richtige Zeichenfolge stand in der Antwort; die Ausführung durchlief den Stammbaum nicht vollständig. Gleiche Endpunkte beweisen nicht, dass der Weg dazwischen vertrauenswürdig ist.

Die ganze Ahnenreihe zählt

Die W3C-Empfehlung Content Security Policy Level 2 vom Dezember 2016 definierte frame-ancestors. Vor dem Laden der geschützten Ressource listet der Browser sämtliche übergeordneten Fenster auf. Für jedes prüft er die Dokument-URL gegen die erlaubten Quellen. Eine einzige Abweichung beendet den Ladevorgang. Bei A/B/A scheitert B, auch wenn oben A steht.

Das W3C stellte diese Vollprüfung ausdrücklich der obersten Ebene gegenüber, auf die viele SAMEORIGIN-Implementierungen beschränkt waren. frame-ancestors löse X-Frame-Options ab; bei zwei gleichzeitig gesendeten Regeln solle die CSP-Regel gelten. Mehrere erlaubte Herkünfte waren nun ebenfalls möglich. Die entscheidende Änderung war aber die Prüftiefe.

Auch der Transport der Regel war Teil ihrer Wirkung. X-Frame-Options musste als HTTP-Header ankommen; eine Angabe im meta http-equiv-Element wurde laut RFC ignoriert. frame-ancestors darf ebenfalls nicht aus einer meta-Policy stammen. Ein allgemeines default-src 'none' setzt kein Verbot für übergeordnete Rahmen. Der Seitenbetreiber musste die Einbettungsregel ausdrücklich in der vom Browser verarbeiteten Antwort angeben.

Der Eigentümer der Seite kann bestimmen, wer sie umgeben darf. Nur der Browser des Besuchers sieht die tatsächliche Verschachtelung. Die geschriebene Grenze schützt erst, wenn diese Verschachtelung vollständig geprüft wird.