Same-origin policy

Same-Origin Policy (SOP) — фундаментальная модель безопасности веб-платформы, ограничивающая взаимодействие между ресурсами, загруженными из разных источников. Политика определяет правила доступа скриптов к данным и объектам браузера, если они принадлежат различным доменам.

Источником (origin) считается комбинация трёх компонентов:

  • Протокол (scheme) — например http, https
  • Домен (host) — имя хоста или IP-адрес
  • Порт (port) — сетевой порт

Если хотя бы один из этих компонентов отличается, браузер рассматривает ресурсы как находящиеся в разных источниках.

Примеры:

URL Origin
https://example.com https, example.com, 443
http://example.com http, example.com, 80
https://example.com:8080 https, example.com, 8080
https://api.example.com https, api.example.com, 443

Следовательно:

  • https://example.com и https://example.com/pageодин origin
  • https://example.com и http://example.comразные origin
  • https://example.com и https://api.example.comразные origin

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


Причины существования политики

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

Типичный сценарий угрозы:

  1. Пользователь авторизуется на банковском сайте.
  2. Затем открывает вредоносную страницу в другой вкладке.
  3. Вредоносный скрипт пытается прочитать данные из банковского сайта.

Same-Origin Policy блокирует подобный доступ. Скрипты вредоносной страницы не могут получить доступ к:

  • DOM другой страницы
  • cookies другого сайта
  • данным локального хранилища
  • содержимому HTTP-ответов

Области применения Same-Origin Policy

Политика применяется к нескольким важным механизмам браузера.

Доступ к DOM

JavaScript-код может свободно взаимодействовать только с документами того же origin.

Пример ограничения:

const iframe = document.querySelector("iframe");

console.log(iframe.contentWindow.document);

Если iframe загружает страницу с другого домена, браузер выбрасывает исключение:

Blocked a frame with origin from accessing a cross-origin frame

Это предотвращает манипуляции с чужими документами.


XMLHttpRequest и Fetch

Запросы к API также контролируются Same-Origin Policy.

fetch("https://api.other-site.com/data")

Без дополнительных разрешений браузер блокирует доступ к ответу, даже если запрос был отправлен.

Запрос может выполниться, но JavaScript не сможет прочитать результат.


Cookies и хранилища

SOP изолирует пользовательские данные:

  • localStorage
  • sessionStorage
  • cookies
  • IndexedDB

Каждый origin имеет собственное пространство хранения.

localStorage.setItem("token", "123");

Скрипт другого сайта не сможет получить этот токен.


Особенности загрузки ресурсов

Некоторые ресурсы разрешено загружать между доменами без ограничений, однако доступ к их содержимому ограничен.

Разрешённые загрузки:

  • изображения (img)
  • стили (link)
  • скрипты (script)
  • видео и аудио
  • iframe

Пример:

<img src="https://cdn.example.com/image.png">

Изображение будет отображаться, однако JavaScript страницы не получит доступ к пикселям изображения без дополнительных разрешений.


Cross-Origin ограничения Canvas

Canvas предоставляет доступ к пикселям изображений. Поэтому действует дополнительное правило безопасности.

Если изображение загружено с другого origin без разрешения CORS, Canvas становится tainted (загрязнённым).

Пример:

const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");

const img = new Image();
img.src = "https://external-site.com/image.png";

img.onl oad = () => {
  ctx.drawImage(img, 0, 0);
  canvas.toDataURL();
};

Попытка получить данные приведёт к ошибке:

SecurityError: Tainted canvases may not be exported

Связь Same-Origin Policy и CORS

Для легального взаимодействия между доменами используется механизм CORS (Cross-Origin Resource Sharing).

Сервер может явно разрешить доступ, отправив специальные HTTP-заголовки.

Пример ответа сервера:

Access-Control-Allow-Origin: https://example.com

После этого браузер позволит странице example.com читать ответ.

Fetch-запрос:

fetch("https://api.service.com/data")
  .then(response => response.json())
  .then(data => console.log(data));

Если сервер правильно настроен, запрос будет успешно обработан.


Preflight-запросы

Некоторые cross-origin операции считаются потенциально опасными. Перед их выполнением браузер отправляет предварительный запрос (preflight).

Используется метод OPTIONS.

Пример:

OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type

Сервер отвечает:

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type

Только после успешного ответа основной запрос будет выполнен.


Исключения и ослабления политики

Несмотря на строгие ограничения, браузеры поддерживают механизмы безопасного взаимодействия между origin.

Основные методы:

postMessage

Позволяет безопасно передавать данные между окнами и iframe.

iframe.contentWindow.postMessage(
  { type: "DATA", value: 42 },
  "https://example.com"
);

Получение сообщения:

window.addEventListener("message", (event) => {
  if (event.origin !== "https://example.com") return;
  console.log(event.data);
});

Проверка origin обязательна для предотвращения атак.


document.domain

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

document.domain = "example.com";

Тогда страницы:

  • app.example.com
  • admin.example.com

могут взаимодействовать друг с другом.

Этот подход считается устаревшим и постепенно выводится из использования.


JSONP

До появления CORS применялся обходной механизм через тег script.

<script src="https://api.example.com/data?callback=handleData"></script>

Ответ сервера:

handleData({ value: 123 });

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

Метод имеет серьёзные ограничения и практически не используется в современных системах.


Same-Origin Policy и тестирование доступности

При использовании axe-core политика Same-Origin влияет на анализ содержимого страниц.

Библиотека работает внутри DOM текущего документа и не имеет доступа к содержимому:

  • iframe другого origin
  • защищённых embedded-документов
  • сторонних виджетов

Пример:

axe.run(document);

Если страница содержит внешний iframe:

<iframe src="https://external-site.com/widget"></iframe>

axe-core сможет проверить:

  • наличие атрибутов title
  • корректность структуры iframe

но не сможет анализировать DOM внутри него, поскольку браузер блокирует доступ.


Работа axe-core с iframe

При тестировании доступности необходимо учитывать изоляцию origin.

Сценарии:

  1. Same-origin iframe

axe-core может выполнить анализ содержимого.

const frame = document.querySelector("iframe");
axe.run(frame.contentDocument);
  1. Cross-origin iframe

DOM недоступен.

Единственное решение — запускать axe внутри самой страницы iframe.


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

Same-Origin Policy влияет на архитектуру инструментов проверки доступности:

  • браузерные расширения
  • автоматические тесты
  • CI-сканеры

Типичные ограничения:

  • невозможность анализа сторонних виджетов
  • необходимость запуска сканера внутри каждой страницы
  • отдельная проверка embedded-приложений

Поэтому системы тестирования доступности часто используют:

  • headless браузеры
  • инжекцию скриптов в каждый origin
  • параллельное сканирование страниц

Безопасность и ограничения обхода

Попытки обхода Same-Origin Policy считаются серьёзной уязвимостью. Современные браузеры дополнительно усиливают изоляцию:

  • Site Isolation
  • Cross-Origin Opener Policy (COOP)
  • Cross-Origin Embedder Policy (COEP)
  • Content Security Policy (CSP)

Эти механизмы усиливают защиту от атак:

  • Spectre
  • XS-Leaks
  • data exfiltration

В результате взаимодействие между различными источниками становится строго контролируемым.


Роль политики в современной архитектуре веб-приложений

Same-Origin Policy влияет на проектирование систем:

  1. Разделение фронтенда и API
  2. Использование CORS-политик
  3. Размещение ресурсов на CDN
  4. Изоляция микрофронтендов

При разработке инструментов анализа доступности, включая axe-core, необходимо учитывать:

  • границы origin
  • ограничения доступа к DOM
  • необходимость запуска проверок в каждом независимом контексте страницы.

Same-Origin Policy остаётся одним из ключевых механизмов безопасности веб-платформы, определяющим правила взаимодействия между ресурсами и скриптами различных источников.