Узнайте, почему для использования мощных функций, таких как SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
и таймера высокого разрешения с большей точностью, необходима изоляция между источниками.
Введение
В статье «Как сделать ваш сайт «изолированным от разных источников» с помощью COOP и COEP» мы объяснили, как перейти в состояние «изолированного от разных источников» с помощью COOP и COEP. В этой статье объясняется, почему изоляция от разных источников необходима для реализации мощных функций браузера.
Фон
Интернет основан на политике единого источника : функции безопасности, которая ограничивает взаимодействие документов и скриптов с ресурсами из другого источника. Этот принцип ограничивает способы доступа веб-сайтов к ресурсам из разных источников. Например, документ из https://a.example
не сможет получить доступ к данным, размещённым по адресу https://b.example
.
Однако политика единого источника имела некоторые исторические исключения. Любой веб-сайт может:
- Встраивание кросс-доменных фреймов
- Включайте ресурсы из разных источников, такие как изображения или сценарии.
- Открывать всплывающие окна с кросс-источником со ссылкой на DOM
Если бы веб можно было разработать с нуля, этих исключений не существовало бы. К сожалению, к тому времени, как веб-сообщество осознало ключевые преимущества строгой политики единства происхождения, веб уже полагался на эти исключения.
Побочные эффекты безопасности, связанные с такой нестрогой политикой единого источника, были устранены двумя способами. Один из них заключался в внедрении нового протокола CORS (Cross Origin Resource Sharing), цель которого — гарантировать, что сервер разрешает общий доступ к ресурсу с заданным источником. Другой способ — неявное исключение прямого доступа скриптов к ресурсам из разных источников с сохранением обратной совместимости. Такие ресурсы из разных источников называются «непрозрачными». Например, именно поэтому манипуляция пикселями изображения из разных источников через CanvasRenderingContext2D
невозможна, если к изображению не применён CORS.
Все эти политические решения принимаются в рамках группы контекста просмотра.
Долгое время сочетание CORS и непрозрачных ресурсов было достаточным для обеспечения безопасности браузеров. Иногда обнаруживались пограничные случаи (например, уязвимости JSON ), которые требовали исправления, но в целом принцип запрета прямого доступа на чтение к необработанным байтам кросс-источниковых ресурсов оказался успешным.
Всё изменилось с появлением Spectre , который делает потенциально читаемыми любые данные, загружаемые в ту же группу контекста просмотра, что и ваш код. Измеряя время выполнения определённых операций, злоумышленники могут определить содержимое кэшей процессора, а через них и содержимое памяти процесса. Такие атаки по времени возможны с помощью низкоуровневых таймеров, существующих в платформе, но их можно ускорить с помощью высокоуровневых таймеров, как явных (например, performance.now()
), так и неявных (например, SharedArrayBuffer
s). Если evil.com
внедряет изображение из другого источника, они могут использовать атаку Spectre для чтения его пиксельных данных, что делает защиту, основанную на «непрозрачности», неэффективной.
В идеале все запросы из разных источников должны явно проверяться сервером, владеющим ресурсом. Если сервер, владеющий ресурсом, не обеспечивает такую проверку, данные никогда не попадут в группу контекста просмотра злоумышленника и, следовательно, останутся вне досягаемости атак Spectre, которые может осуществить веб-страница. Мы называем это состоянием изоляции из разных источников. Именно в этом и заключается суть COOP+COEP.
В состоянии кросс-источниковой изоляции запрашивающий сайт считается менее опасным, что открывает доступ к мощным функциям, таким как SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
и высокоточным таймерам , которые в противном случае могли бы использоваться для атак типа Spectre. Кроме того, это предотвращает изменение document.domain
.
Политика кросс-происхождения встраивания
Политика кросс-оригинального встраивания (COEP) запрещает документу загружать любые кросс-оригинальные ресурсы, которые явно не предоставляют этому документу разрешение (с помощью CORP или CORS). С помощью этой функции вы можете объявить, что документ не может загружать такие ресурсы.
Чтобы активировать эту политику, добавьте к документу следующий HTTP-заголовок:
Cross-Origin-Embedder-Policy: require-corp
COEP принимает единственное значение require-corp
. Это обеспечивает соблюдение политики, согласно которой документ может загружать только ресурсы из того же источника или ресурсы, явно отмеченные как загружаемые из другого источника.
Чтобы ресурсы можно было загружать из другого источника, они должны поддерживать либо Cross Origin Resource Sharing (CORS), либо Cross Origin Resource Policy (CORP).
Совместное использование ресурсов из разных источников
Если ресурс с кросс-источником поддерживает Cross Origin Resource Sharing (CORS) , вы можете использовать атрибут crossorigin
для его загрузки на свою веб-страницу, не опасаясь блокировки со стороны COEP.
<img src="https://third-party.example.com/image.jpg" crossorigin>
Например, если этот ресурс изображения обслуживается заголовками CORS, используйте атрибут crossorigin
, чтобы запрос на извлечение ресурса использовал режим CORS . Это также предотвращает загрузку изображения без установки заголовков CORS.
Аналогичным образом вы можете извлекать данные из разных источников с помощью метода fetch()
, который не требует специальной обработки, если сервер отвечает правильными заголовками HTTP .
Политика использования ресурсов из разных источников
Политика ресурсов между источниками (CORP) изначально была введена как дополнительная опция для защиты ваших ресурсов от загрузки из другого источника. В контексте COEP CORP может определять политику владельца ресурса относительно того, кто может загружать ресурс.
Заголовок Cross-Origin-Resource-Policy
принимает три возможных значения:
Cross-Origin-Resource-Policy: same-site
Ресурсы, помеченные как same-site
могут быть загружены только с этого же сайта.
Cross-Origin-Resource-Policy: same-origin
Ресурсы, помеченные как same-origin
могут быть загружены только из одного и того же источника.
Cross-Origin-Resource-Policy: cross-origin
Ресурсы, помеченные как cross-origin
могут быть загружены любым веб-сайтом. ( Это значение было добавлено в спецификацию CORP вместе с COEP.)
Политика открытия кросс-источников
Политика открытия окон из разных источников (COOP) позволяет изолировать окно верхнего уровня от других документов, помещая их в отдельную группу контекста просмотра, чтобы они не могли напрямую взаимодействовать с окном верхнего уровня. Например, если документ с COOP открывает всплывающее окно, его свойство window.opener
будет равно null
. Кроме того, свойство .closed
ссылки на него в окне открытия будет возвращать true
.
Заголовок Cross-Origin-Opener-Policy
принимает три возможных значения:
Cross-Origin-Opener-Policy: same-origin
Документы, помеченные как имеющие same-origin
могут использовать одну и ту же группу контекста просмотра с документами того же происхождения, которые также явно помечены как имеющие same-origin
.
Cross-Origin-Opener-Policy: same-origin-allow-popups
Документ верхнего уровня с same-origin-allow-popups
сохраняет ссылки на все свои всплывающие окна, которые либо не устанавливают COOP, либо отказываются от изоляции, устанавливая COOP в unsafe-none
.
Cross-Origin-Opener-Policy: unsafe-none
unsafe-none
является значением по умолчанию и позволяет добавлять документ в группу контекста просмотра открывающего его объекта, если только сам открывающий объект не имеет COOP same-origin
.
Краткое содержание
Если вам нужен гарантированный доступ к мощным функциям, таким как SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
или высокоточным таймерам , помните, что в вашем документе должны использоваться как COEP со значением require-corp
, так и COOP со значением same-origin
. При отсутствии любого из них браузер не гарантирует достаточной изоляции для безопасного включения этих мощных функций. Вы можете определить состояние вашей страницы, проверив, возвращает ли self.crossOriginIsolated
значение true
.
Изучите шаги по реализации этого в статье Создание «междоменной изоляции» вашего веб-сайта с помощью COOP и COEP .