Izolacja witryn dla programistów stron internetowych

Chrome 67 w wersji na komputery ma nową funkcję o nazwie izolacja witryn domyślnie włączona. Ten Artykuł wyjaśnia, na czym polega izolacja witryn, dlaczego jest potrzebna i dlaczego deweloperzy stron internetowych zdać sobie sprawę z tego.

Czym jest izolacja witryn?

Internet umożliwia m.in. oglądanie filmów o kotach i zarządzanie portfelami kryptowalutowymi. ale nie chcesz, żeby firma fluffycats.example miała dostęp do Twoich cennych kryptowalut. Na szczęście dzięki Same-Origin witryny zwykle nie mogą uzyskiwać dostępu do swoich danych wewnątrz przeglądarki Zasady. Złośliwe witryny mogą jednak próbować ominąć tę zasadę, aby zaatakować inne witryny i czasami w kodzie przeglądarki można znaleźć błędy zabezpieczeń, które wymuszają zasadę Same-Origin. Zespół Chrome stara się jak najszybciej usuwać takie błędy.

Izolacja witryn to funkcja zabezpieczeń Chrome, która zapewnia dodatkową linię obrony, takich ataków jest mniejsze. Dzięki niemu strony z różnych witryn są zawsze umieszczane na różne procesy, z których każdy działa w środowisku piaskownicy, który ogranicza jego uprawnienia. Blokuje też procesowi otrzymywania określonych typów danych wrażliwych z innych witryn. Jako izolacji witryn znacznie trudniej jest stosować spekulacje spekulacyjne dla złośliwej witryny, ataki typu side-channel, takie jak Spectre, w celu kradzieży danych z innych witryn. Gdy zespół Chrome skończy na temat dodatkowych zasad, izolacja witryny będzie działać nawet wtedy, gdy strona atakująca reguł w ramach osobnego procesu.

Skuteczna izolacja witryn utrudnia niezaufanym witrynom dostęp do informacji lub kradzież ich z Twoich kont na innych stronach. Zapewnia dodatkową ochronę przed różnymi typami Błędy w zabezpieczeniach, takie jak niedawnych ataków typu bocznego Meltdown i Spectre.

Więcej informacji na temat izolacji witryn znajdziesz w naszym artykule na blogu Google o bezpieczeństwie.

Blokowanie odczytu w różnych źródłach

Nawet jeśli wszystkie strony należące do różnych witryn będą przetwarzane w osobnym procesie, strony nadal mogą w słuszny sposób wysyłać żądania określonych zasobów podrzędnych w różnych witrynach, takich jak obrazy i JavaScript. Złośliwa strona internetowa może użyć tagu Element <img>, aby wczytać plik JSON z danymi poufnymi, takimi jak saldo w banku:

<img src="https://your-bank.example/balance.json" />
<!-- Note: the attacker refused to add an `alt` attribute, for extra evil points. -->

Bez izolacji witryny zawartość pliku JSON znalazłaby się w pamięci mechanizmu renderowania Gdy mechanizm renderowania zauważa, że jest to nieprawidłowy format obrazu i nie renderuje go, obrazu. Osoba przeprowadzająca atak może jednak wykorzystać lukę, taką jak Spectre, potencjalnie odczytać kawałek pamięci.

Zamiast <img>, atakujący może też użyć <script>, aby przekazać dane wrażliwe pamięć:

<script src="https://your-bank.example/balance.json"></script>

Cross-Origin Read Blokowanie, czyli CORB, to nowa funkcja zabezpieczeń, która zapobiega treściom balance.json od momentu wejścia do pamięci procesu renderowania z uwzględnieniem jego typu MIME.

Przyjrzyjmy się, jak działa CORB. Witryna może żądać od serwera 2 typów zasobów:

  1. zasoby danych, takie jak dokumenty HTML, XML i JSON;
  2. zasoby multimedialne, takie jak obrazy, JavaScript, CSS czy czcionki;

Witryna może otrzymywać zasoby danych z własnego lub innego źródła za pomocą mniej rygorystyczne nagłówki CORS, takie jak Access-Control-Allow-Origin: *. Z drugiej strony zasoby multimedialne mogą być dodawane z dowolnego źródła origin, nawet bez mniej rygorystycznych nagłówków CORS.

CORB zapobiega odbieraniu przez mechanizm renderowania zasobu danych z innych domen (np. kodu HTML, XML lub JSON), jeśli:

  • zasób ma nagłówek X-Content-Type-Options: nosniff
  • CORS nie zezwala wprost na dostęp do zasobu

Jeśli zasób danych z innej domeny nie ma ustawionego nagłówka X-Content-Type-Options: nosniff, CORB próbuje wykryć treść odpowiedzi, aby określić, czy jest to HTML, XML czy JSON. To jest konieczne, ponieważ niektóre serwery WWW są nieprawidłowo skonfigurowane i wyświetlają obrazy na przykład jako text/html.

Zasoby danych zablokowane przez zasadę CORB są przedstawiane procesowi jako puste, chociaż żądanie nadal jest wykonywane w tle. Oznacza to, że złośliwa strona internetowa wykorzystują dane z różnych witryn do kradzieży.

Aby zapewnić optymalne bezpieczeństwo i korzystać z zalet CORB, zalecamy wykonanie tych czynności:

  • Oznacz odpowiedzi prawidłowym nagłówkiem Content-Type. (Na przykład zasoby HTML powinny być wyświetlane jako zasoby JSON z funkcją text/html typ MIME pliku JSON i zasoby XML z atrybutem typu XML MIME).
  • Aby zrezygnować z nagłówka, użyj nagłówka X-Content-Type-Options: nosniff. Bez tego nagłówka Chrome przeprowadza szybką analizę treści, aby potwierdzić, że typ jest prawidłowy, ale nie pozwala na wyświetlanie odpowiedzi, by uniknąć blokowania takich elementów jak pliki JavaScript, lepiej, jeśli samemu zrobisz to, co trzeba.

Aby dowiedzieć się więcej, zapoznaj się z Artykuł na temat CORB dla programistów stron internetowych lub w naszym szczegółowym wyjaśnieniu CORB.

Dlaczego twórcy stron internetowych powinni dbać o izolację witryn?

W większości przypadków izolacja witryn to „zakulisowa” funkcja przeglądarki, która nie dla programistów stron internetowych. Nie jest na przykład żaden nowy interfejs API do udostępniania w internecie. Ogólnie rzecz biorąc, strony nie powinny być w stanie rozróżnić niezależnie od tego, czy działa on z izolacją witryn czy bez niej.

Istnieją jednak pewne wyjątki od tej reguły. Włączenie izolacji witryn wiąże się z kilkoma subtelnymi efekty uboczne, które mogą wpłynąć na Twoją witrynę. Utrzymujemy listę znanych problemów z izolacją witryn, a te najważniejsze opisujemy poniżej.

Układ całej strony nie jest już synchroniczny

W przypadku izolacji witryn nie ma już gwarancji synchronicznego układu całej strony, ponieważ ramki strona może obecnie obejmować wiele procesów. Może to mieć wpływ na strony, jeśli zakładają, że zmiana układu zostanie natychmiast zastosowana we wszystkich klatkach na stronie.

Przyjrzyjmy się np. witrynie o nazwie fluffykittens.example, która komunikuje się z widżet społecznościowy hostowany w social-widget.example:

<!-- https://fluffykittens.example/ -->
<iframe src="https://social-widget.example/" width="123"></iframe>
<script>
  const iframe = document.querySelector('iframe');
  iframe.width = 456;
  iframe.contentWindow.postMessage(
    // The message to send:
    'Meow!',
    // The target origin:
    'https://social-widget.example'
  );
</script>

Początkowo szerokość <iframe> widżetu społecznościowych to 123 piks. Ale też na stronie FluffyKittens, zmienia szerokość na 456 piks. (układ wywołujący) i wysyła wiadomość do widżetu społecznościowego, który ma następujący kod:

<!-- https://social-widget.example/ -->
<script>
  self.onmessage = () => {
    console.log(document.documentElement.clientWidth);
  };
</script>

Za każdym razem, gdy widżet społecznościowy odbiera wiadomość przez interfejs API postMessage, rejestruje szerokość jego elementu podstawowego <html>.

Która wartość szerokości jest rejestrowana? Przed włączeniem izolacji witryn w Chrome odpowiedź brzmiała 456. Uzyskiwanie dostępu document.documentElement.clientWidth wymusza układ, który wcześniej był synchroniczny przed Chrome włączono izolację witryn. Jednak po włączeniu izolacji witryn widżet społecznościowy z innych domen Teraz ponowne układy są realizowane asynchronicznie w oddzielnym procesie. Odpowiedź może więc brzmieć następująco: 123, czyli starą wartość width.

Jeśli strona zmieni rozmiar zasobu <iframe> z innej domeny, a następnie wyśle do niej tag postMessage, z zastosowaniem parametru Izolacja witryny – ramka odbierająca może nie rozpoznać nowego rozmiaru w chwili otrzymania wiadomości. Więcej Może to spowodować nieprawidłowe działanie stron, jeśli założą, że zmiana układu od razu dotyczy wszystkich ramki na stronie.

W tym przykładzie bardziej niezawodne rozwiązanie ustawiłoby element width w ramce nadrzędnej, Wykryj tę zmianę w <iframe>, nasłuchując zdarzenia resize.

Wyładowywanie modułów obsługi może częściej przekraczać limit czasu

Podczas przechodzenia lub zamykania ramki stary dokument oraz wszystkie umieszczone w niej dokumenty ramki podrzędnej wszystkie mają własny moduł obsługi unload. Jeśli nowa nawigacja odbywa się w tym samym procesie renderowania (np. nawigacji na tej samej domenie), moduły obsługi unload starego dokumentu i jego ramek podrzędnych mogą działać za dowolnie długi czas, zanim będzie można zatwierdzić nową nawigację.

addEventListener('unload', () => {
  doSomethingThatMightTakeALongTime();
});

W tej sytuacji moduły obsługi unload we wszystkich klatkach są bardzo niezawodne.

Jednak nawet bez izolacji witryny niektóre nawigacji w głównych klatkach przebiegają w wielu procesach, co ma wpływ unload. Jeśli na przykład przejdziesz z old.example do new.example, wpisując adresu URL na pasku adresu, nawigacja new.example odbywa się w ramach nowego procesu. Wyładowania moduły obsługi interfejsu old.example i jego ramek podrzędnych są uruchamiane w tle w procesie old.example, po wyświetleniu strony new.example, a stare moduły obsługi wyładowywania zostaną zakończone, jeśli nie będą nie powinny zakończyć się w określonym czasie. Ponieważ moduły obsługi wyładowania mogą nie zakończyć się przed upływem limitu czasu, jest mniej niezawodne.

Izolacja witryn powoduje, że cała nawigacja w witrynach jest procesem wieloprocesowym, dzięki czemu dokumenty różne witryny nie mają ze sobą wspólnego procesu. W związku z tym powyższa sytuacja ma zastosowanie jest więcej przypadków, a moduły obsługi wyładowywania w <iframe> s często działają w tle i mają czas oczekiwania opisane powyżej.

Kolejną różnicą wynikającą z izolacji witryn jest nowa, równoległa kolejność modułów obsługi wyładowywania: bez izolacji witryn moduły obsługi wyładowywania z pamięci są uruchamiane w ścisłej kolejności od góry do dołu. Ale dzięki Witrynom Izolacja i obsługa wyładowania działają równolegle w różnych procesach.

Są to podstawowe konsekwencje włączenia izolacji witryn. Zespół Chrome pracuje nad poprawę niezawodności modułów obsługi wyładowywania w typowych przypadkach użycia, gdy jest to możliwe. Jesteśmy także mogą mieć świadomość błędów, w wyniku których moduły obsługi wyładowywania ramki podrzędnej nie są jeszcze w stanie korzystać z pewnych funkcji i pracujemy nad ich rozwiązaniem.

Ważnym elementem obsługi wyładowywania jest wysyłanie pingów na koniec sesji. Najczęściej odbywa się to jako następujące:

addEventListener('pagehide', () => {
  const image = new Image();
  img.src = '/end-of-session';
});

Lepszym podejściem, które jest bardziej niezawodne w świetle tej zmiany, jest stosowanie navigator.sendBeacon zamiast:

addEventListener('pagehide', () => {
  navigator.sendBeacon('/end-of-session');
});

Jeśli chcesz mieć większą kontrolę nad żądaniem, możesz użyć opcji keepalive w interfejsie Fetch API:

addEventListener('pagehide', () => {
  fetch('/end-of-session', {keepalive: true});
});

Podsumowanie

Izolacja witryn utrudnia niezaufanym witrynom dostęp do informacji z Twoich kont w innych witrynach, odizolując każdą witrynę osobno. W ramach tych działań CORB próbuje aby zapobiec uwzględnianiu zasobów danych wrażliwych w procesie renderowania. Dzięki naszym rekomendacjom jak najlepiej wykorzystać nowe funkcje zabezpieczeń.

Dzięki Alex Moshchuk Charlie Reis Jason Miller Nasko Oskov, Philip Walton, Shubhie Panicker Thomas Steiner za przeczytanie wersji roboczej tego artykułu i przekazanie opinii.