Durch Partitionierung des Caches für mehr Sicherheit und Datenschutz sorgen

Im Allgemeinen kann Caching die Leistung verbessern, indem Daten gespeichert werden, sodass zukünftige Anfragen für dieselben Daten schneller verarbeitet werden. Beispielsweise kann eine im Cache gespeicherte Ressource aus dem Netzwerk einen Umlauf zum Server vermeiden. Bei einem im Cache gespeicherten Berechnungsergebnis kann die Zeit für die Durchführung derselben Berechnung ausgelassen werden.

In Chrome wird der Cache-Mechanismus auf unterschiedliche Weise eingesetzt. Ein Beispiel hierfür ist der HTTP-Cache.

So funktioniert der HTTP-Cache von Chrome derzeit

Ab Version 85 speichert Chrome aus dem Netzwerk abgerufene Ressourcen im Cache und verwendet die entsprechenden Ressourcen-URLs als Cache-Schlüssel. (Ein Cache-Schlüssel wird verwendet, um eine im Cache gespeicherte Ressource zu identifizieren.)

Das folgende Beispiel zeigt, wie ein einzelnes Bild im Cache gespeichert und in drei verschiedenen Kontexten verarbeitet wird:

Cache-Schlüssel: https://x.beispiel/doge.png
Cache-Schlüssel: { https://x.example/doge.png }

Ein Nutzer besucht eine Seite (https://a.example), die ein Bild anfordert (https://x.example/doge.png). Das Bild wird vom Netzwerk angefordert und mit https://x.example/doge.png als Schlüssel im Cache gespeichert.

Cache-Schlüssel: https://x.beispiel/doge.png
Cache-Schlüssel: { https://x.example/doge.png }

Derselbe Nutzer besucht eine andere Seite (https://b.example), die dasselbe Bild anfordert (https://x.example/doge.png). Der Browser prüft seinen HTTP-Cache, um festzustellen, ob diese Ressource bereits im Cache gespeichert ist. Dabei wird die Bild-URL als Schlüssel verwendet. Der Browser findet eine Übereinstimmung im Cache und verwendet die im Cache gespeicherte Version der Ressource.

Cache-Schlüssel: https://x.beispiel/doge.png
Cache-Schlüssel: { https://x.example/doge.png }

Dabei spielt es keine Rolle, ob das Bild aus einem iFrame geladen wird. Wenn der Nutzer eine andere Website (https://c.example) mit einem iFrame (https://d.example) besucht und der iFrame dasselbe Bild (https://x.example/doge.png) anfordert, kann der Browser das Bild trotzdem aus dem Cache laden, da der Cache-Schlüssel auf allen Seiten derselbe ist.

Dieser Mechanismus funktioniert seit Langem im Hinblick auf die Leistung gut. Die Zeit, die eine Website benötigt, um auf HTTP-Anfragen zu antworten, kann jedoch zeigen, dass der Browser in der Vergangenheit auf dieselbe Ressource zugegriffen hat. Dadurch wird der Browser für Sicherheits- und Datenschutzangriffe geöffnet. Beispiel:

  • Erkennen, ob ein Nutzer eine bestimmte Website besucht hat: Angreifer können den Browserverlauf eines Nutzers ermitteln, indem sie prüfen, ob der Cache eine Ressource enthält, die für eine bestimmte Website oder Kohorte von Websites spezifisch sein könnte.
  • Cross-Site-Search-Angriff: Ein Angreifer kann erkennen, ob sich ein beliebiger String in den Suchergebnissen des Nutzers befindet. Dazu wird geprüft, ob sich ein Bild ohne Suchergebnisse, das von einer bestimmten Website verwendet wird, im Cache des Browsers befindet.
  • Websiteübergreifendes Tracking: Im Cache können Cookie-ähnliche Kennungen als websiteübergreifendes Tracking gespeichert werden.

Um diesen Risiken vorzubeugen, wird der HTTP-Cache von Chrome ab Chrome 86 partitioniert.

Wie wirkt sich die Cache-Partitionierung auf den HTTP-Cache von Chrome aus?

Bei der Cache-Partitionierung werden im Cache gespeicherte Ressourcen zusätzlich zur Ressourcen-URL mit einem neuen „Netzwerkisolierungsschlüssel“ verschlüsselt. Der Netzwerkisolierungsschlüssel setzt sich aus der Website auf oberster Ebene und der Website mit dem aktuellen Frame zusammen.

Sehen Sie sich noch einmal das vorherige Beispiel an, um zu sehen, wie die Cache-Partitionierung in verschiedenen Kontexten funktioniert:

Cache-Schlüssel { https://a.beispiel, https://a.beispiel, https://x.beispiel/doge.png}
Cache-Schlüssel: { https://a.example, https://a.example, https://x.example/doge.png }

Ein Nutzer besucht eine Seite (https://a.example), die ein Bild anfordert (https://x.example/doge.png). In diesem Fall wird das Bild vom Netzwerk angefordert und mit einem Tupel aus https://a.example (Website der obersten Ebene), https://a.example (Website mit dem aktuellen Frame) und https://x.example/doge.png (Ressourcen-URL) als Schlüssel im Cache gespeichert. Wenn die Ressourcenanfrage vom Frame der obersten Ebene stammt, sind die Website der obersten Ebene und die Website des aktuellen Frames im Netzwerkisolationsschlüssel identisch.

Cache-Schlüssel { https://a.beispiel, https://a.beispiel, https://x.beispiel/doge.png}
Cache-Schlüssel: { https://b.example, https://b.example, https://x.example/doge.png }

Derselbe Nutzer besucht eine andere Seite (https://b.example), die dasselbe Bild (https://x.example/doge.png) anfordert. Obwohl im vorherigen Beispiel dasselbe Bild geladen wurde, handelt es sich nicht um einen Cache-Treffer, da der Schlüssel nicht übereinstimmt.

Das Bild wird aus dem Netzwerk angefordert und mit einem Tupel aus https://b.example, https://b.example und https://x.example/doge.png als Schlüssel im Cache gespeichert.

Cache-Schlüssel { https://a.beispiel, https://a.beispiel, https://x.beispiel/doge.png}
Cache-Schlüssel: { https://a.example, https://a.example, https://x.example/doge.png }

Jetzt kehrt der Nutzer zu https://a.example zurück, aber diesmal ist das Bild (https://x.example/doge.png) in einen iFrame eingebettet. In diesem Fall ist der Schlüssel ein Tupel, das https://a.example, https://a.example und https://x.example/doge.png enthält, und es tritt ein Cache-Treffer auf. Wenn die Website der obersten Ebene und der iFrame dieselbe sind, kann die Ressource verwendet werden, die mit dem Frame der obersten Ebene im Cache gespeichert wurde.

Cache-Schlüssel { https://a.beispiel, https://a.beispiel, https://x.beispiel/doge.png}
Cache-Schlüssel: { https://a.example, https://c.example, https://x.example/doge.png }

Der Nutzer ist wieder bei https://a.example, aber diesmal wird das Bild in einem iFrame von https://c.example gehostet.

In diesem Fall wird das Image aus dem Netzwerk heruntergeladen, da sich im Cache keine Ressource befindet, die mit dem Schlüssel aus https://a.example, https://c.example und https://x.example/doge.png übereinstimmt.

Cache-Schlüssel { https://a.beispiel, https://a.beispiel, https://x.beispiel/doge.png}
Cache-Schlüssel: { https://a.example, https://c.example, https://x.example/doge.png }

Was geschieht, wenn die Domain eine Subdomain oder eine Portnummer enthält? Der Nutzer ruft https://subdomain.a.example auf. Dort wird ein iFrame (https://c.example:8080) eingebettet, der das Bild anfordert.

Da der Schlüssel auf Grundlage von "scheme://eTLD+1" erstellt wird, werden Subdomains und Portnummern ignoriert. Daher tritt ein Cache-Treffer auf.

Cache-Schlüssel { https://a.beispiel, https://a.beispiel, https://x.beispiel/doge.png}
Cache-Schlüssel: { https://a.example, https://c.example, https://x.example/doge.png }

Was passiert, wenn der iFrame mehrmals verschachtelt ist? Der Nutzer ruft https://a.example auf. Dort wird ein iFrame (https://b.example) eingebettet, der einen weiteren iFrame (https://c.example) einbettet, der schließlich das Bild anfordert.

Da der Schlüssel aus dem obersten Frame (https://a.example) und dem sofortigen Frame entnommen wird, der die Ressource (https://c.example) lädt, tritt ein Cache-Treffer auf.

Häufig gestellte Fragen

Ist die Funktion in meinem Chrome bereits aktiviert? Wie kann ich das prüfen?

Die Funktion wird bis Ende 2020 eingeführt. So prüfen Sie, ob Ihre Chrome-Instanz dies bereits unterstützt:

  1. Öffnen Sie chrome://net-export/ und klicken Sie auf Protokollierung auf Laufwerk starten.
  2. Geben Sie an, wo die Protokolldatei auf Ihrem Computer gespeichert werden soll.
  3. Du kannst eine Minute lang mit Chrome im Web surfen.
  4. Gehen Sie zurück zu chrome://net-export/ und klicken Sie auf Protokoll anhalten.
  5. Bewegen bis https://netlog-viewer.appspot.com/#import.
  6. Klicken Sie auf Datei auswählen und übergeben Sie die gespeicherte Protokolldatei.

Sie sehen die Ausgabe der Protokolldatei.

Suchen Sie auf derselben Seite nach SplitCacheByNetworkIsolationKey. Wenn Experiment_[****] darauf folgt, ist die HTTP-Cache-Partitionierung in Ihrem Chrome aktiviert. Wenn darauf Control_[****] oder Default_[****] folgt, ist es nicht aktiviert.

Wie kann ich die HTTP-Cache-Partitionierung in Chrome testen?

Zum Testen der HTTP-Cache-Partitionierung in Chrome müssen Sie Chrome mit einem Befehlszeilen-Flag starten: --enable-features=SplitCacheByNetworkIsolationKey. Folgen Sie der Anleitung unter Chromium mit Flags ausführen. Hier erfahren Sie, wie Sie Chrome mit einem Befehlszeilen-Flag auf Ihrer Plattform starten.

Muss ich als Webentwickler etwas tun, um auf diese Änderung zu reagieren?

Dies ist zwar keine funktionsgefährdende Änderung, kann aber bei einigen Webdiensten die Leistung beeinträchtigen.

Beispielsweise können diejenigen, die große Mengen an hochgradig im Cache speicherbaren Ressourcen auf vielen Websites bereitstellen (z. B. Schriftarten und beliebte Skripts), einen Anstieg des Traffics verzeichnen. Außerdem verlassen sich diejenigen, die solche Dienste nutzen, möglicherweise stärker von ihnen.

Es gibt einen Vorschlag, gemeinsam genutzte Bibliotheken datenschutzfreundlich zu aktivieren: Web Shared Libraries (Präsentationsvideo), die aber noch geprüft werden.

Welche Auswirkungen hat diese Verhaltensänderung?

Die Cache-Fehlerrate insgesamt erhöht sich um etwa 3,6%, die Änderungen am FCP (First Contentful Paint) sind gering (ca. 0,3%) und der Gesamtanteil der aus dem Netzwerk geladenen Byte erhöht sich um etwa 4%. Weitere Informationen zu den Auswirkungen auf die Leistung finden Sie in der Erläuterung der HTTP-Cache-Partitionierung.

Ist das standardisiert? verhalten sich andere Browser anders?

"HTTP-Cache-Partitionen" sind in der Abrufspezifikation standardisiert, obwohl sich Browser anders verhalten:

  • Chrome: verwendet das Schema://eTLD+1 der obersten Ebene und das Frame schema://eTLD+1
  • Safari: mit eTLD+1 der obersten Ebene
  • Firefox: Implementierung geplant mit dem Top-Level-Schema://eTLD+1 und erwägen, einen zweiten Schlüssel wie Chrome einzubinden

Wie werden Abrufe von Workern behandelt?

Dedizierte Worker verwenden denselben Schlüssel wie ihr aktueller Frame. Service Worker und Shared Worker sind komplizierter, da sie von mehreren Standorten der obersten Ebene gemeinsam verwendet werden können. Die Lösung dafür wird derzeit noch diskutiert.

Weitere Informationen