Можно смело сказать, что 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.
- Запросите токен для вашего источника.
- Добавьте токен на свои страницы. Это можно сделать двумя способами:
- Добавьте тег
<meta>
origin-trial
в заголовок каждой страницы. Например, это может выглядеть примерно так:
<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- Если вы можете настроить свой сервер, вы также можете добавить токен с помощью HTTP-заголовка
Origin-Trial
. Заголовок ответа должен выглядеть примерно так:
Origin-Trial: TOKEN_GOES_HERE
- Добавьте тег
Дальнейшее чтение
- Руководство по обеспечению изоляции между источниками
- Как изолировать страницы от других источников
- Почему необходима изоляция между источниками
Баннерное фото Дэниела Грегуара на Unsplash