Сделайте свой веб-сайт «изолированным от разных источников»; использование COOP и COEP

Используйте COOP и COEP, чтобы настроить изолированную среду с несколькими источниками и включить мощные функции, такие как SharedArrayBuffer , performance.measureUserAgentSpecificMemory() и таймер высокого разрешения с большей точностью.

Обновления

  • 21 июня 2022 г .: Рабочие сценарии также требуют осторожности, если включена изоляция между источниками. Добавил некоторые пояснения.
  • 5 августа 2021 г .: JS Self-Profiling API был упомянут как один из API, требующих изоляции между источниками, но, отражая недавнее изменение направления , он был удален.
  • 6 мая 2021 г .: На основании отзывов и сообщений о проблемах мы решили скорректировать график использования SharedArrayBuffer ни на одном изолированном сайте с перекрестным происхождением, который не будет ограничен в Chrome M92.
  • 16 апреля 2021 г .: добавлены примечания о новом режиме COEP без учетных данных и всплывающих окнах COOP с одинаковым происхождением, которые являются смягченным условием изоляции между источниками.
  • 5 марта 2021 г .: сняты ограничения для SharedArrayBuffer , performance.measureUserAgentSpecificMemory() и функций отладки, которые теперь полностью включены в Chrome 89. Добавлены будущие возможности performance.now() и performance.timeOrigin , которые будут иметь более высокую точность.
  • 19 февраля 2021 г .: добавлено примечание о политике allow="cross-origin-isolated" и функциях отладки в DevTools.
  • 15 октября 2020 г .: self.crossOriginIsolated доступен в Chrome 87. Учитывая это, document.domain является неизменяемым, когда self.crossOriginIsolated возвращает true . performance.measureUserAgentSpecificMemory() завершает свою пробную версию и включен по умолчанию в Chrome 89. Shared Array Buffer в Android Chrome будет доступен в Chrome 88.

Некоторые веб-API повышают риск атак по побочным каналам, таких как Spectre. Чтобы снизить этот риск, браузеры предлагают изолированную среду на основе согласия, называемую изоляцией между источниками. В изолированном состоянии между источниками веб-страница сможет использовать привилегированные функции, в том числе:

API Описание
SharedArrayBuffer Требуется для потоков WebAssembly. Это доступно в Android Chrome 88. Версия для настольных компьютеров в настоящее время включена по умолчанию с помощью изоляции сайта , но потребует изолированного состояния между источниками и будет отключена по умолчанию в Chrome 92 .
performance.measureUserAgentSpecificMemory() Доступно в Chrome 89.
performance.now() , performance.timeOrigin В настоящее время доступно во многих браузерах с разрешением, ограниченным 100 микросекундами или выше. При изоляции между источниками разрешение может составлять 5 микросекунд или выше.
Функции, которые будут доступны в изолированном состоянии с перекрестным происхождением.

Изолированное состояние перекрестного происхождения также предотвращает модификации document.domain . (Возможность изменить document.domain позволяет осуществлять связь между документами одного сайта и считается лазейкой в ​​политике одного и того же источника.)

Чтобы перейти в изолированное состояние между разными источниками, вам необходимо отправить следующие HTTP-заголовки в основной документ:

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

Эти заголовки инструктируют браузер блокировать загрузку ресурсов или iframe, которые не выбрали загрузку документами из разных источников, и не позволяют окнам из разных источников напрямую взаимодействовать с вашим документом. Это также означает, что ресурсы, загружаемые из разных источников, требуют согласия.

Вы можете определить, находится ли веб-страница в изолированном состоянии между разными источниками, проверив self.crossOriginIsolated .

В этой статье показано, как использовать эти новые заголовки. В следующей статье я расскажу больше об истории и контексте.

Разверните COOP и COEP, чтобы изолировать ваш веб-сайт от перекрестного происхождения.

Интегрируйте COOP и COEP

1. Установите заголовок Cross-Origin-Opener-Policy: same-origin в документе верхнего уровня.

Если включить COOP: same-origin в документе верхнего уровня, окна с одним и тем же источником и окна, открытые из документа, будут иметь отдельную группу контекста просмотра, если только они не находятся в одном и том же источнике с одинаковым параметром COOP. Таким образом, для открытых окон применяется изоляция, а взаимная связь между обоими окнами отключается.

Группа контекста просмотра — это набор окон, которые могут ссылаться друг на друга. Например, документ верхнего уровня и его дочерние документы, встроенные через <iframe> . Если веб-сайт ( https://a.example ) открывает всплывающее окно ( https://b.example ), открывающее окно и всплывающее окно используют один и тот же контекст просмотра, поэтому они имеют доступ друг к другу через API-интерфейсы DOM, такие как как window.opener .

Группа контекста просмотра

Вы можете проверить, находятся ли средство открытия окна и его открывающий объект в отдельных группах контекста просмотра из DevTools .

2. Убедитесь, что на ресурсах включен CORP или CORS.

Убедитесь, что все ресурсы на странице загружены с HTTP-заголовками CORP или CORS. Этот шаг необходим для четвертого шага, включающего COEP .

Вот что вам нужно сделать в зависимости от характера ресурса:

  • Если ожидается, что ресурс будет загружен только из одного и того же источника , установите заголовок Cross-Origin-Resource-Policy: same-origin .
  • Если ожидается, что ресурс будет загружен только с того же сайта, но из перекрестного источника , установите заголовок Cross-Origin-Resource-Policy: same-site .
  • Если ресурс загружается из перекрестного источника(ов), находящегося под вашим контролем , установите заголовок Cross-Origin-Resource-Policy: cross-origin если это возможно.
  • Для ресурсов перекрестного происхождения, над которыми вы не имеете контроля:
    • Используйте атрибут crossorigin в HTML-теге загрузки, если ресурс обслуживается с помощью CORS. (Например, <img src="***" crossorigin> .)
    • Попросите владельца ресурса поддержать CORS или CORP.
  • Для iframe следуйте тем же принципам, что и выше, и установите Cross-Origin-Resource-Policy: cross-origin (или same-site , same-origin в зависимости от контекста).
  • Скрипты, загруженные с помощью WebWorker , должны обслуживаться из одного и того же источника, поэтому вам не нужны заголовки CORP или CORS.
  • Для документа или работника, обслуживаемого с помощью COEP: require-corp , подресурсы с перекрестным происхождением, загруженные без CORS, должны установить заголовок Cross-Origin-Resource-Policy: cross-origin чтобы разрешить внедрение. Например, это относится к <script> , importScripts , <link> , <video> , <iframe> и т. д.

3. Используйте HTTP-заголовок COEP Report-Only для оценки встроенных ресурсов.

Прежде чем полностью включить COEP, вы можете выполнить пробный прогон, используя заголовок Cross-Origin-Embedder-Policy-Report-Only чтобы проверить, действительно ли политика работает. Вы будете получать отчеты, не блокируя встроенный контент.

Рекурсивно примените это ко всем документам, включая документ верхнего уровня, iframe и рабочие сценарии. Информацию о HTTP-заголовке только для отчетов см. в разделе «Наблюдение за проблемами с помощью Reporting API ».

4. Включите COEP

Убедившись, что все работает и что все ресурсы могут быть успешно загружены, переключите заголовок Cross-Origin-Embedder-Policy-Report-Only на заголовок Cross-Origin-Embedder-Policy с тем же значением для всех документов, включая те, которые встроены через iframe и рабочие скрипты.

Определите, удалось ли выполнить изоляцию с помощью self.crossOriginIsolated .

Свойство self.crossOriginIsolated возвращает true , когда веб-страница находится в изолированном состоянии между источниками и все ресурсы и окна изолированы в одной группе контекста просмотра. Вы можете использовать этот API, чтобы определить, успешно ли вы изолировали группу контекста просмотра и получили доступ к мощным функциям, таким как performance.measureUserAgentSpecificMemory() .

Проблемы отладки с помощью Chrome DevTools

Для ресурсов, отображаемых на экране, таких как изображения, довольно легко обнаружить проблемы COEP, поскольку запрос будет заблокирован, а на странице будет указано отсутствующее изображение. Однако для ресурсов, которые не обязательно оказывают визуальное воздействие, таких как сценарии или стили, проблемы COEP могут остаться незамеченными. Для этого используйте панель DevTools Network. Если возникла проблема с COEP, вы должны увидеть (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep) в столбце Статус .

Проблемы COEP в столбце «Состояние» панели «Сеть».

Затем вы можете щелкнуть запись, чтобы просмотреть более подробную информацию.

Подробности о проблеме COEP отображаются на вкладке «Заголовки» после щелчка сетевого ресурса на панели «Сеть».

Вы также можете определить статус iframe и всплывающих окон через панель «Приложение» . Перейдите в раздел «Кадры» слева и разверните «верх», чтобы увидеть структуру ресурса.

Вы можете проверить статус iframe, например наличие SharedArrayBuffer и т. д.

Инспектор iframe Chrome DevTools

Вы также можете проверить статус всплывающих окон, например, изолированы ли они от перекрестного происхождения.

Инспектор всплывающих окон Chrome DevTools

Наблюдайте за проблемами с помощью Reporting API

API отчетов — это еще один механизм, с помощью которого вы можете обнаруживать различные проблемы. Вы можете настроить API отчетов, чтобы дать браузеру пользователя указание отправлять отчет каждый раз, когда COEP блокирует загрузку ресурса или COOP изолирует всплывающее окно. Chrome поддерживает Reporting API начиная с версии 69 для различных целей, включая COEP и COOP.

Чтобы узнать, как настроить Reporting API и настроить сервер для получения отчетов, перейдите в раздел «Использование Reporting API» .

Пример отчета COEP

Пример полезной нагрузки отчета COEP при блокировке ресурса перекрестного происхождения выглядит следующим образом:

[{
  "age": 25101,
  "body": {
    "blocked-url": "https://third-party-test.glitch.me/check.svg?",
    "blockedURL": "https://third-party-test.glitch.me/check.svg?",
    "destination": "image",
    "disposition": "enforce",
    "type": "corp"
  },
  "type": "coep",
  "url": "https://cross-origin-isolation.glitch.me/?coep=require-corp&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]

Пример отчета COOP

Пример полезной нагрузки отчета COOP при изолированном открытии всплывающего окна выглядит следующим образом:

[{
  "age": 7,
  "body": {
    "disposition": "enforce",
    "effectivePolicy": "same-origin",
    "nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
    "type": "navigation-from-response"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

Когда разные группы контекста просмотра пытаются получить доступ друг к другу (только в режиме «только отчет»), COOP также отправляет отчет. Например, отчет при попытке использования postMessage() будет выглядеть так:

[{
  "age": 51785,
  "body": {
    "columnNumber": 18,
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "lineNumber": 83,
    "property": "postMessage",
    "sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
    "type": "access-from-coop-page-to-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
  "age": 51785,
  "body": {
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "property": "postMessage",
    "type": "access-to-coop-page-from-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

Заключение

Используйте комбинацию HTTP-заголовков COOP и COEP, чтобы перевести веб-страницу в специальное изолированное состояние между источниками. Вы сможете проверить self.crossOriginIsolated , чтобы определить, находится ли веб-страница в изолированном состоянии от разных источников.

Мы будем обновлять этот пост по мере появления новых функций в этом изолированном состоянии с несколькими источниками, а также дальнейших улучшений в DevTools, связанных с COOP и COEP.

Ресурсы