Обновления SharedArrayBuffer в Android Chrome 88 и Desktop Chrome 92

Можно смело сказать, что SharedArrayBuffer пришлось нелегко в интернете, но всё постепенно налаживается. Вот что вам нужно знать:

Вкратце

  • SharedArrayBuffer в настоящее время поддерживается в Firefox 79+ и появится в Android Chrome 88. Однако он доступен только для страниц, изолированных от разных источников .
  • SharedArrayBuffer в настоящее время доступен в десктопном Chrome, но начиная с Chrome 92 он будет доступен только на изолированных страницах с разными источниками. Если вы не уверены, что успеете внести это изменение, вы можете зарегистрироваться на пробную версию Origin , чтобы сохранить текущее поведение как минимум до версии Chrome 113.
  • Если вы планируете включить кросс-доменную изоляцию для дальнейшего использования SharedArrayBuffer , оцените, как это повлияет на другие кросс-доменные элементы вашего сайта, например, на размещение рекламы. Проверьте, используется ли SharedArrayBuffer какими-либо сторонними ресурсами, чтобы понять последствия и получить рекомендации.

Обзор изоляции между источниками

Вы можете сделать страницу изолированной от других источников , снабдив ее следующими заголовками:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

После этого ваша страница не сможет загружать кросс-доменный контент, если ресурс явно не разрешит это через заголовок Cross-Origin-Resource-Policy или заголовки CORS ( Access-Control-Allow-* и т. д.).

Также имеется API для создания отчетов , с помощью которого можно собирать данные о запросах, которые не были выполнены из-за Cross-Origin-Embedder-Policy и Cross-Origin-Opener-Policy .

Если вы считаете, что не успеете внести эти изменения к выходу Chrome 92, вы можете зарегистрироваться на пробную версию Origin, чтобы сохранить текущее поведение Chrome для настольных компьютеров как минимум до выхода Chrome 113.

Дополнительные рекомендации и информацию о межпроисхождении изоляции см. в разделе « Дополнительная литература» внизу этой страницы.

Как мы сюда попали?

SharedArrayBuffer появился в Chrome 60 (это июль 2017 года, для тех, кто воспринимает время в датах, а не в версиях Chrome), и всё было отлично. Целых 6 месяцев.

В январе 2018 года в некоторых популярных процессорах была обнаружена уязвимость. Подробности смотрите в объявлении , но по сути это означало, что код мог использовать высокоточные таймеры для чтения памяти, к которой у него не должно быть доступа.

Это представляло собой проблему для нас, производителей браузеров, поскольку мы хотим разрешить сайтам выполнять код в формате JavaScript и WASM, но строго контролировать объём памяти, к которому этот код может получить доступ. Если вы перейдёте на мой сайт, я не смогу прочитать ничего с сайта интернет-банкинга, который вы также открыли. Более того, я даже не должен знать, что ваш сайт интернет-банкинга открыт. Это основы веб-безопасности.

Чтобы смягчить эту проблему, мы уменьшили разрешение наших таймеров высокого разрешения, таких как performance.now() . Однако вы можете создать таймер высокого разрешения с помощью SharedArrayBuffer , изменяя память в коротком цикле в рабочем потоке и считывая её обратно в другом потоке. Эффективно решить эту проблему без серьёзного влияния на код, написанный с благими намерениями, было невозможно, поэтому SharedArrayBuffer был полностью отключён.

Общим способом снижения риска является обеспечение того, чтобы системный процесс веб-страницы не содержал конфиденциальных данных из других источников. Chrome изначально инвестировал в многопроцессную архитектуру ( помните комикс? ), но всё равно бывали случаи, когда данные с нескольких сайтов могли попасть в один и тот же процесс:

<iframe src="https://your-bank.example/balance.json"></iframe>
<script src="https://your-bank.example/balance.json"></script>
<link rel="stylesheet" href="https://your-bank.example/balance.json" />
<img src="https://your-bank.example/balance.json" />
<video src="https://your-bank.example/balance.json"></video>
<!-- …and more… -->

Эти API имеют «устаревшее» поведение, позволяющее использовать контент из других источников без согласия с их стороны. Эти запросы выполняются с использованием cookie-файлов другого источника, поэтому это полноценный запрос с авторизацией. В настоящее время новые API требуют согласия с помощью CORS от другого источника.

Мы обошли эти устаревшие API, запретив контенту попадать в процесс веб-страницы, если он выглядел «некорректным», и назвали это блокировкой чтения из-за границы источника (cross-origin read blocking ). Таким образом, в вышеприведённых случаях мы не допускали попадание JSON в процесс, поскольку этот формат недопустим ни для одного из этих API. То есть, за исключением iframe. Для iframe мы помещаем контент в другой процесс.

Благодаря этим мерам мы вновь добавили SharedArrayBuffer в Chrome 68 (июль 2018 г.), но только на десктопах. Из-за дополнительных требований к процессам мы не смогли реализовать то же самое на мобильных устройствах. Также было отмечено, что решение Chrome было неполным, поскольку мы блокировали только «неправильные» форматы данных, в то время как допустимые CSS/JS-коды/изображения по предполагаемым URL-адресам могут содержать конфиденциальные данные (хотя это и нетипично).

Специалисты по веб-стандартам объединились, чтобы разработать более полное кроссбраузерное решение. Решение заключалось в том, чтобы предоставить страницам возможность сообщить: «Я настоящим отказываюсь от возможности добавлять контент из других источников в этот процесс без их согласия». Это заявление делается через заголовки COOP и COEP, передаваемые вместе со страницей. Браузер обеспечивает это, а взамен страница получает доступ к SharedArrayBuffer и другим API с аналогичными возможностями. Другие источники могут согласиться на встраивание контента с помощью Cross-Origin-Resource-Policy или CORS .

Firefox был первым, кто выпустил SharedArrayBuffer с этим ограничением в версии 79 (июль 2020 г.).

Затем, в январе 2021 года, я написал эту статью, и вы её читаете. Здравствуйте.

И вот где мы сейчас находимся. Chrome 88 возвращает SharedArrayBuffer в Android для страниц, изолированных от разных источников, а Chrome 92 предъявляет те же требования к десктопам как для обеспечения согласованности, так и для достижения полной изоляции от разных источников.

Отсрочка изменения версии Chrome для ПК

Это временное исключение в виде «пробной версии источника», которая даёт больше времени для реализации изолированных страниц с разными источниками. Оно позволяет использовать SharedArrayBuffer , не требуя изоляции страницы с разными источниками. Исключение действует с Chrome 113 и действует только в десктопной версии Chrome.

  1. Запросите токен для вашего источника.
  2. Добавьте токен на свои страницы. Это можно сделать двумя способами:
    • Добавьте тег <meta> origin-trial в заголовок каждой страницы. Например, это может выглядеть примерно так:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Если вы можете настроить свой сервер, вы также можете добавить токен с помощью HTTP-заголовка Origin-Trial . Заголовок ответа должен выглядеть примерно так:
      Origin-Trial: TOKEN_GOES_HERE

Дальнейшее чтение

Баннерное фото Дэниела Грегуара на Unsplash