Uzyskiwanie bezpieczeństwa i prywatności przez partycjonowanie pamięci podręcznej

Ogólnie rzecz biorąc, pamięć podręczna może zwiększyć wydajność, ponieważ przechowuje dane, dzięki czemu kolejne żądania dotyczące tych samych danych są obsługiwane szybciej. Na przykład zasób z pamięci podręcznej z sieci może uniknąć dwukierunkowego połączenia z serwerem. Zapisany w pamięci podręcznej wynik obliczeń może pominąć czas potrzebny na wykonanie tych samych obliczeń.

W Chrome mechanizm pamięci podręcznej jest wykorzystywany na różne sposoby, a przykładem jest pamięć podręczna HTTP.

Jak działa obecnie pamięć podręczna HTTP w Chrome

Od wersji 85 Chrome przechowuje w pamięci podręcznej zasoby pobrane z sieci, używając ich adresów URL jako kluczy pamięci podręcznej. (klucz pamięci podręcznej służy do identyfikacji zasobu w pamięci podręcznej).

Ten przykład pokazuje, jak pojedynczy obraz jest przechowywany w pamięci podręcznej i traktowany w 3 różnych kontekstach:

Klucz pamięci podręcznej: https://x.example/doge.png
Klucz pamięci podręcznej: { https://x.example/doge.png }

Użytkownik odwiedza stronę (https://a.example), która prosi o obraz (https://x.example/doge.png). Żądanie dotyczące obrazu jest wysyłane do sieci i przechowywane w pamięci podręcznej z kluczem https://x.example/doge.png.

Klucz pamięci podręcznej: https://x.example/doge.png
Klucz pamięci podręcznej: { https://x.example/doge.png }

Ten sam użytkownik odwiedza inną stronę (https://b.example), która żąda tego samego obrazu (https://x.example/doge.png). Przeglądarka sprawdza pamięć podręczną HTTP, aby sprawdzić, czy ten zasób jest już w niej zapisany (jako klucz służy URL obrazu). Przeglądarka znajduje dopasowanie w pamięci podręcznej, więc używa zmagazynowanej wersji zasobu.

Klucz pamięci podręcznej: https://x.example/doge.png
Klucz pamięci podręcznej: { https://x.example/doge.png }

Nie ma znaczenia, czy obraz jest wczytywany z elementa iframe. Jeśli użytkownik odwiedza inną witrynę (https://c.example) z elementem iframe (https://d.example), a element iframe żąda tego samego obrazu (https://x.example/doge.png), przeglądarka może nadal wczytać obraz z pamięci podręcznej, ponieważ klucz pamięci podręcznej jest taki sam na wszystkich stronach.

Ten mechanizm od dawna dobrze się sprawdzał pod względem skuteczności. Czas, jaki zajmuje witrynie odpowiedź na żądania HTTP, może jednak ujawnić, że przeglądarka wcześniej uzyskała dostęp do tego samego zasobu. Może to narazić przeglądarkę na ataki na bezpieczeństwo i prywatność, takie jak:

  • Wykrywanie, czy użytkownik odwiedził określoną witrynę: atakujący może wykryć historię przeglądania użytkownika, sprawdzając, czy w pamięci podręcznej znajduje się zasób, który może być specyficzny dla konkretnej witryny lub grupy witryn.
  • Atak na wyszukiwarkę w wielu witrynach: Osoba atakująca może wykryć, czy dowolny ciąg znaków występuje w wynikach wyszukiwania użytkownika, sprawdzając, czy obraz „brak wyników wyszukiwania” używany przez konkretną witrynę znajduje się w pamięci podręcznej przeglądarki.
  • Śledzenie w witrynach: pamięć podręczna może służyć do przechowywania identyfikatorów podobnych do plików cookie jako mechanizmu śledzenia w witrynach.

Aby temu zapobiegać, Chrome w wersji 86 podzieli pamięć podręczną HTTP na partycje.

Jak partycjonowanie pamięci podręcznej wpłynie na pamięć podręczną HTTP w Chrome?

W przypadku partycjonowania pamięci podręcznej zaszyfrowane zasoby będą miały klucze oparte na nowym „kluczu izolacji sieci” (oprócz adresu URL zasobu). Klucz izolacji sieci składa się z witryny najwyższego poziomu i witryny bieżącego kadru.

.

Aby zobaczyć, jak działa podział pamięci podręcznej w różnych kontekstach, jeszcze raz spójrz na poprzedni przykład:

Klucz pamięci podręcznej { https://a.example, https://a.example, https://x.example/doge.png}
Klucz pamięci podręcznej: { https://a.example, https://a.example, https://x.example/doge.png }

Użytkownik odwiedza stronę (https://a.example), która żąda obrazu (https://x.example/doge.png). W tym przypadku obraz jest żądany z sieci i przechowywany w pamięci podręcznej za pomocą tuple zawierającej https://a.example (witryna najwyższego poziomu), https://a.example (witryna bieżącego kadru) i https://x.example/doge.png (adres URL zasobu) jako klucz. (Pamiętaj, że gdy żądanie zasobu pochodzi z ramki najwyższego poziomu, witryna najwyższego poziomu i witryna bieżącej ramki w kluczu izolacji sieci są takie same).

Klucz pamięci podręcznej { https://a.example, https://a.example, https://x.example/doge.png}
Klucz pamięci podręcznej: { https://b.example, https://b.example, https://x.example/doge.png }

Ten sam użytkownik odwiedza inną stronę (https://b.example), która żąda tego samego obrazu (https://x.example/doge.png). Chociaż w poprzednim przykładzie załadowany był ten sam obraz, to ze względu na niepasujący klucz nie zostanie on odebrany z pamięci podręcznej.

Obraz jest żądany z sieci i przechowywany w pamięci podręcznej za pomocą tupla zawierającego https://b.example, https://b.examplehttps://x.example/doge.png jako klucz.

Klucz pamięci podręcznej { https://a.example, https://a.example, https://x.example/doge.png}
Klucz pamięci podręcznej: { https://a.example, https://a.example, https://x.example/doge.png }

Użytkownik wraca na stronę https://a.example, ale tym razem obraz (https://x.example/doge.png) jest umieszczony w ramce iframe. W tym przypadku klucz to tupla zawierająca wartości https://a.example, https://a.examplehttps://x.example/doge.png, a do pamięci podręcznej trafia klucz. (Pamiętaj, że gdy witryna najwyższego poziomu i element iframe znajdują się w tej samej witrynie, można użyć zasobu z pamięci podręcznej w elemencie iframe najwyższego poziomu.

Klucz pamięci podręcznej { https://a.example, https://a.example, https://x.example/doge.png}
Klucz pamięci podręcznej: { https://a.example, https://c.example, https://x.example/doge.png }

Użytkownik wraca na stronę https://a.example, ale tym razem obraz jest hostowany w iframe z witryny https://c.example.

W tym przypadku obraz jest pobierany z sieci, ponieważ w pamięci podręcznej nie ma zasobu pasującego do klucza zawierającego wartości https://a.example, https://c.examplehttps://x.example/doge.png.

Klucz pamięci podręcznej { https://a.example, https://a.example, https://x.example/doge.png}
Klucz pamięci podręcznej: { https://a.example, https://c.example, https://x.example/doge.png }

Co zrobić, jeśli domena zawiera subdomenę lub numer portu? Użytkownik odwiedza stronę https://subdomain.a.example, która zawiera iframe (https://c.example:8080) z żądaniem przesłania obrazu.

Ponieważ klucz jest tworzony na podstawie „schematu://eTLD+1”, poddomeny i numery portów są ignorowane. W tym przypadku następuje trafienie w pamięci podręcznej.

Klucz pamięci podręcznej { https://a.example, https://a.example, https://x.example/doge.png}
Klucz pamięci podręcznej: { https://a.example, https://c.example, https://x.example/doge.png }

Co zrobić, jeśli iframe jest zagnieżdżony wielokrotnie? Użytkownik odwiedza stronę https://a.example, która zawiera element iframe (https://b.example), który z kolei zawiera kolejny element iframe (https://c.example), który w końcu wysyła żądanie dotyczące obrazu.

Ponieważ klucz jest pobierany z ramki najwyższego poziomu (https://a.example) i ramki natychmiastowej, która wczytuje zasób (https://c.example), następuje trafienie do pamięci podręcznej.

Najczęstsze pytania

Czy jest ona już włączona w Chrome? Jak mogę to sprawdzić?

Ta funkcja jest wdrażana do końca 2020 r. Aby sprawdzić, czy Twoja instancja Chrome już obsługuje tę funkcję:

  1. Otwórz chrome://net-export/ i kliknij Rozpocznij rejestrowanie na dysku.
  2. Określ, gdzie zapisać plik dziennika na komputerze.
  3. Przeglądaj internet w Chrome przez minutę.
  4. Wróć do chrome://net-export/ i kliknij Zatrzymaj rejestrowanie.
  5. Jedź do: https://netlog-viewer.appspot.com/#import.
  6. Kliknij Wybierz plik i podaj zapisany plik dziennika.

Zobaczysz dane wyjściowe pliku dziennika.

Na tej samej stronie znajdź SplitCacheByNetworkIsolationKey. Jeśli po nim następuje Experiment_[****], oznacza to, że w Chrome jest włączone partycjonowanie pamięci podręcznej HTTP. Jeśli jest poprzedzona wartością Control_[****] lub Default_[****], nie jest włączona.

Jak mogę przetestować partycjonowanie pamięci podręcznej HTTP w Chrome?

Aby przetestować partycjonowanie pamięci podręcznej HTTP w Chrome, musisz uruchomić Chrome z flagą wiersza poleceń: --enable-features=SplitCacheByNetworkIsolationKey. Aby dowiedzieć się, jak uruchomić Chrome za pomocą flagi wiersza poleceń na swojej platformie, wykonaj instrukcje podane w artykule Uruchamianie Chromium za pomocą flag.

Czy jako twórca stron internetowych powinienem podjąć jakieś działania w odpowiedzi na tę zmianę?

Nie jest to zmiana powodująca przerwy w działaniu, ale może mieć wpływ na wydajność niektórych usług internetowych.

Na przykład witryny, które dostarczają dużej ilości zasobów z łatwo zapisuje się w pamięci podręcznej (np. czcionek i popularnych skryptów), mogą odnotować wzrost ruchu. Osoby korzystające z takich usług mogą być na nich bardziej uzależnione.

(Istnieje propozycja włączenia współdzielonych bibliotek w sposób zapewniający ochronę prywatności, zwany współdzielonymi bibliotekami internetowymi (prezentacja wideo), ale jest ona nadal rozważana).

Jaki jest wpływ tej zmiany zachowania?

Ogólny współczynnik braku pamięci podręcznej wzrasta o około 3,6%, zmiany w FCP (pierwsze wyrenderowanie treści) są niewielkie (o około 0,3%), a ogólna liczba bajtów wczytanych z sieci wzrasta o około 4%. Więcej informacji o wpływie na wydajność znajdziesz w artykule o partycjonowaniu pamięci podręcznej HTTP.

Czy jest to standard? Czy inne przeglądarki działają inaczej?

„Partycje pamięci podręcznej HTTP” są standardowe w specyfikacji pobierania, ale przeglądarki zachowują się inaczej:

  • Chrome używa schematu najwyższego poziomu://eTLD+1 i ramki schematu://eTLD+1
  • Safari używa najwyższego poziomu eTLD+1.
  • Firefox planujemy wdrożenie z użyciem schematu najwyższego poziomu://eTLD+1 i rozważamy dodanie drugiego klucza, tak jak w Chrome.

Jak traktowane są pobierania z usług?

Specjalne instancje robocze używają tego samego klucza co ich bieżąca ramka. Usługi i wspólne usługi są bardziej skomplikowane, ponieważ mogą być współdzielone przez wiele witryn najwyższego poziomu. Obecnie rozważamy rozwiązanie tego problemu.

Zasoby