Междоменная изоляция: заголовки и SharedArrayBuffer
Узнайте, что меняет междоменная изоляция, как взаимодействуют COOP и COEP и как проверить встроенные ресурсы до включения SharedArrayBuffer.
BotBrowser Team
Нужна структурированная документация по теме Платформа?
Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.
Междоменная изоляция представляет собой состояние безопасности браузера, возникающее при совместимом наборе политик ответа и отношений между документами. В поддерживаемых браузерах она может разрешить веб-возможности, например SharedArrayBuffer, но не делает автоматически доступными все ресурсы с других источников. Типичная конфигурация верхнего уровня сочетает Cross-Origin-Opener-Policy: same-origin (COOP) со значением Cross-Origin-Embedder-Policy (COEP), например require-corp или, если поддержка и сценарий это допускают, credentialless. Затем документ может проверить window.crossOriginIsolated и подтвердить фактическое состояние браузера.
Решение о развертывании не сводится к «добавить два заголовка». COOP меняет отношения страницы с окнами, открытыми с других источников; COEP меняет условия загрузки встроенных ресурсов с других источников. Это может затронуть вход через всплывающее окно, платежи, аналитику, медиа, шрифты, фреймы и сторонние скрипты. До включения кода, зависящего от функций, доступных только при изоляции, составьте перечень зависимостей, проверьте их реальные ответы и вводите политику поэтапно, предусмотрев явный резервный путь и откат. Это архитектурное решение с ценой совместимости.
Что меняет междоменная изоляция
Модель междоменной изоляции в WHATWG HTML описывает состояние браузера, а не сетевой туннель и не свойство, которое может установить скрипт. Страница выбирает более строгие отношения с другими контекстами просмотра и встроенными ресурсами. Если браузер принимает применимую политику и необходимые отношения документов, он сообщает результат через crossOriginIsolated. Именно это значение следует записывать как результат выполнения: наличие одного заголовка в ответе сервера само по себе не доказывает изоляцию загруженного документа.
Разные источники могут отличаться схемой, хостом или портом. Поэтому поддомен той же организации тоже может быть другим источником. Границы источников не совпадают с границами сайтов; имя CDN, домен ресурсов или фрейм, размещенный заказчиком, могут изменить применимую политику. Ресурс, работающий на локальном стенде, может иметь другой источник и конфигурацию ответа в production.
Междоменную изоляцию часто обсуждают вместе с SharedArrayBuffer, но это лишь один сценарий. Некоторые приложения используют его для поддерживаемых библиотек или возможностей среды выполнения. Точные условия доступности могут отличаться между браузерами и версиями платформ. Безопасный контекст и изолированный документ часто являются необходимыми условиями, но не гарантируют наличие каждой функции во всех средах. Проверяйте данные поддержки нужного API и тестируйте развернутый документ. Не выводите доступность из строки User-Agent или одного наличия заголовка.
window.crossOriginIsolated сообщает, считает ли браузер изолированной текущую глобальную среду. Значение не объясняет, какой заголовок или встроенный ресурс помешал изоляции. Полезный диагностический отчет связывает это логическое значение с конечным URL документа, относящимися к делу заголовками, версией браузера и контролируемым перечнем ресурсов. Ограничьте отчет фактами конфигурации; пользовательские данные и посторонние атрибуты браузера ему не нужны.
У COOP и COEP разные задачи
COOP управляет отношениями документа с контекстами просмотра верхнего уровня, включая отношения opener. При Cross-Origin-Opener-Policy: same-origin в соответствующих случаях страница отделяется от документов с других источников в группе контекстов просмотра. Это усиливает изоляцию окон, но может изменить сценарии, зависящие от window.opener, например возврат результата из окна входа на исходную страницу. В справочнике MDN по COOP описаны значения политики и их эффекты. Проверяйте вход, оплату и поддержку через всплывающие окна, не предполагая, что интеграции останутся неизменными.
COEP управляет загрузкой встроенных ресурсов с других источников. При Cross-Origin-Embedder-Policy: require-corp ресурс обычно нужно запрашивать через CORS с успешным CORS-ответом либо отдавать с совместимым ответом Cross-Origin-Resource-Policy (CORP). Ресурс, который раньше загружался запросом без CORS, может быть заблокирован, если он не разрешает встраивание. Владельцу ресурса или CDN может понадобиться вернуть Access-Control-Allow-Origin для CORS-запроса либо подходящий Cross-Origin-Resource-Policy для допустимого ресурса без CORS. Нужный заголовок зависит от типа ресурса, учетных данных и предполагаемой границы общего доступа.
Режим COEP credentialless может снять требование CORP для некоторых ресурсов без CORS, загружая их без учетных данных. Это меняет поведение запроса: cookies и другие учетные данные для него не отправляются. Перед выбором проверьте поддержку и подробное поведение по актуальной документации браузера. Это не универсальный переключатель совместимости; он не подходит ресурсам, которым нужна аутентификация. В руководстве MDN о междоменной изоляции описана комбинация политик и последствия для приложения.
Эти функции дополняют друг друга. Один COOP не включает проверки встроенных ресурсов COEP. В типичной изолированной конфигурации один COEP также не обеспечивает требуемое разделение контекстов верхнего уровня. Итоговое состояние страницы зависит от всей политики и отношений документов, а не от ручного значения. Не ослабляйте политику глобально ради загрузки одного стороннего скрипта: определите ресурс и его владельца, затем выберите подходящий CORS, CORP, одобренный прокси или альтернативную интеграцию.
Встроенные ресурсы и границы источников
Перед применением COEP составьте перечень всех ресурсов, которые страница может встраивать или запрашивать: скриптов, таблиц стилей, шрифтов, изображений, аудио, видео, Worker, вложенных фреймов и ресурсов стороннего кода. Классифицируйте каждый как ресурс того же источника, другого источника с CORS, другого источника с CORP или интеграцию, несовместимую с выбранной политикой. Проверяйте реальные сетевые ответы в staging. URL ресурса сам по себе не показывает, есть ли в ответе требуемый заголовок, меняет ли редирект источник и совместим ли CORS-ответ запроса с учетными данными.
Для каждой зависимости зафиксируйте владельца и решение в таблице совместимости:
| Случай зависимости | Что проверить | Решение при развертывании |
|---|---|---|
| Ресурс приложения с того же источника | Конечный URL и состояние ответа | Оставить тот же источник и проверить область редиректов |
| Ресурс другого источника для публичного использования | Режим CORS и Access-Control-Allow-Origin либо подходящий CORP | Согласовать настройку с владельцем ресурса и проверить реальный ответ |
| Междоменному запросу нужны учетные данные | Режим учетных данных, точный разрешенный источник и заголовки ответа | Задать явный контракт CORS, не заменять его режимом credentialless |
| Сторонний ресурс не может разрешить встраивание | Владелец, назначение и критичность | Заменить, использовать прокси по одобренному дизайну, отложить или сохранить резервный путь без изоляции |
| Всплывающее окно или фрейм другого источника | Поведение opener, источник фрейма и отношения политик | Проверить полный пользовательский сценарий с целевой политикой |
Междоменный iframe является отдельным документом со своим источником и отношениями политик. Не считайте, что значение crossOriginIsolated верхней страницы автоматически описывает каждый дочерний фрейм или предоставляет ему все возможности. Подтвердите правила встраивания и делегирование, необходимое конкретной функции, а затем проверьте состояние самого дочернего документа в тестовом примере с ожидаемым источником. Фрейму также может понадобиться собственная совместимая политика ответа. Если вы не контролируете фрейм, согласуйте условия с его владельцем до использования внутри него функции, требующей изоляции.
Политика должна соответствовать принципу минимальных привилегий. Разрешайте только необходимые приложению источники и типы ресурсов, не давая сторонним интеграциям незаметно расширять доступ. Ответ CORS с подстановочным знаком может подходить публичному ресурсу без учетных данных, но не является универсальным решением для аутентифицированных данных. Значения CORP тоже задают, кто может встраивать ответ; выбирайте значение под ожидаемые отношения, а не самое широкое по умолчанию. Зафиксируйте ответственного за каждый заголовок, особенно если страницей, CDN, поставщиком идентификации и встроенным сервисом управляют разные команды.
Детерминированный тест развертывания
Этот тест показывает состояние изоляции, сравнивает его с ожиданием из тестового случая и удаляет временный DOM даже при ошибке проверки или отчета. Размещайте его на том же источнике и через тот же путь настройки заголовков, что и приложение. Для изолированной кандидатной среды задайте ожидаемое значение true; для контрольной среды без полной политики укажите отдельное ожидание. Не выводите ожидание из проверяемого значения.
async function checkIsolation(expected) {
const host = document.createElement('section');
const status = document.createElement('output');
status.setAttribute('aria-live', 'polite');
host.append(status);
document.body.append(host);
try {
const isolated = window.crossOriginIsolated === true;
const sharedMemoryAvailable = typeof SharedArrayBuffer === 'function';
const passed = expected ? isolated && sharedMemoryAvailable : isolated === expected;
status.textContent = `${passed ? 'PASS' : 'FAIL'}: isolated=${isolated}; SharedArrayBuffer=${sharedMemoryAvailable}`;
console.assert(passed, status.textContent);
if (expected) console.assert(sharedMemoryAvailable, 'Expected SharedArrayBuffer in this declared browser case');
return { passed, isolated, sharedMemoryAvailable, visibleResult: status.textContent };
} finally {
host.remove();
}
}
// Конфигурация теста задает ожидание для проверяемого источника.
await checkIsolation(true);
Тест сообщает два разных факта: состояние изоляции браузера и доступность SharedArrayBuffer в этой среде. Поддерживаемый браузерный случай может проверять оба условия; для браузера вне заявленной области поддержки можно зафиксировать отсутствие API и проверить резервный путь продукта. У резервного пути должен быть собственный ожидаемый результат, его нельзя выдавать за успешную изоляцию. Пример не выделяет общую память, не запускает Worker и не выполняет измерений. Он проверяет конфигурацию ответа и доступность среды выполнения без дополнительной нагрузки.
Для проверки совместимости ресурсов загрузите на небольшой собственной странице по одному характерному ресурсу другого источника из каждой необходимой категории. Назначьте каждому стабильный URL теста и проверьте видимый результат загрузки или ошибки. Разделите случаи политик по разным тестам, чтобы ошибка шрифта не скрыла результат скрипта или фрейма. Добавляйте редиректы и учетные данные только тогда, когда их использует production-зависимость. При завершении удалите тестовые узлы и закройте изолированный тестовый контекст; не меняйте общие production-данные.
Развертывание, наблюдение и откат
Развертывайте изменения поэтапно. Сначала составьте перечень междоменных зависимостей и определите их владельцев. Затем настройте источник предварительной проверки с COOP и выбранным значением COEP, после чего запустите тест и весь пользовательский сценарий. Проверяйте заголовки в конечном ответе документа, а не только на балансировщике или в исходном конфигурационном файле: ответ могут менять переадресации, правила CDN, обработчики фоновых сценариев и маршруты по хосту. После реальной навигации проверьте crossOriginIsolated и протестируйте каждый важный ресурс в режиме запроса, применяемом в production.
До широкого запуска проверьте сценарии между контекстами просмотра: аутентификацию через всплывающее окно, передачу платежа, фреймы заказчиков, виджеты помощи и интеграции, использующие ссылку opener. Проверьте также версии браузеров на границах заявленной поддержки и контрольный случай с резервным путем. Сохраняйте краткий отчет с конечным URL, сборкой браузера, значениями COOP и COEP, состоянием изоляции, отказавшими ресурсами, источниками фреймов и видимым результатом. Не включайте секреты, данные аккаунтов и посторонние сведения профиля.
Развертывание готово только тогда, когда изоляция наблюдается там, где она ожидается, важные ресурсы загружаются при заявленной политике, а пользователи могут завершить основную задачу при отсутствии функции. Если выпуск блокирует сторонний ресурс, сохраните резервный путь или замените интеграцию; не ослабляйте политику глобально без документированного решения. Ошибка изоляции является результатом конфигурации, который нужно диагностировать, а не поводом незаметно менять проверки.
Подготовьте откат до изменения production-заголовков. Сохраните прежнюю политику и версию приложения. Если новая политика ломает важную интеграцию, совместно восстановите прежнюю работавшую политику и путь приложения, затем повторите тот же тест, чтобы проверить ожидаемое не изолированное состояние и резервный путь. В версии отката удалите код, зависящий от функции, доступной только при изоляции, либо защитите его проверкой среды выполнения. Сохраняйте безопасный транспорт и остальные защитные заголовки; откат не является основанием для HTTP или удаления доказательств тестирования.
Что может проверить BotBrowser
BotBrowser поддерживает авторизованную проверку приложений в контролируемых контекстах браузера: команда может запускать собственный тест в отдельном контексте на заявленной сборке браузера, проверять состояние изоляции во время выполнения и сравнивать видимый резервный путь, не перенося состояние из постороннего сценария. В документации BotBrowser по изоляции нескольких аккаунтов описаны отдельные контексты для независимых сессий. BotBrowser не может изолировать документ между источниками, предоставлять заголовки COOP или COEP, менять ответы CORS/CORP внешнего ресурса, сохранять поведение всплывающего окна, которое политика намеренно разделяет, или гарантировать поддержку SharedArrayBuffer на каждой платформе. Основой остаются модель междоменной изоляции WHATWG HTML и конфигурация развертывания сайта. Используйте BotBrowser для наблюдения за заявленным сценарием; владельцы приложения и инфраструктуры отвечают за контракты ресурсов, выбор политик, совместимость и откат.
См. также руководство по проверке версий браузера, руководство по безопасным контекстам и руководство по совместимости браузерных API. В них рассматриваются данные для проверки версии, требования к безопасному контексту и планирование резервных вариантов API; эта статья посвящена политикам ответа и ресурсам, необходимым для междоменной изоляции.
Зафиксируйте решение о выпуске вместе с владельцами каждой политики и контракта ресурса. Тогда откат можно проверить по фактам: команда отличит изменение заголовка документа, переадресацию, правило CDN или встроенную зависимость. Ограничьте запись техническими ответами и видимыми результатами и повторяйте те же проверки после каждого изменения политики.
Если необязательная зависимость не работает, зафиксируйте видимый резервный путь. Если зависимость обязательна, отложите выпуск до подтверждения совместимого ответа её владельцем.
Источники
Похожие статьи
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.