Разделение хранилища

Для усиления конфиденциальности пользователей и борьбы с межсайтовым отслеживанием по сторонним каналам Chrome теперь изолирует большинство API-интерфейсов хранения и связи в сторонних контекстах с помощью процесса, называемого разделением хранилища.

Статус реализации

Функция включена для всех пользователей Chrome 115 и более поздних версий. Аналогичные усилия по разделению хранилища также предпринимаются или планируются в других основных браузерах, таких как Firefox и Safari. Предложение по разделению хранилища на GitHub открыто для дальнейшего обсуждения.

Что такое разбиение хранилища на разделы?

Чтобы предотвратить определенные типы межсайтового отслеживания по сторонним каналам, Chrome разделяет API-интерфейсы хранения и связи в сторонних контекстах.

Без разделения хранилища сайт может объединять данные с разных сайтов, чтобы отслеживать пользователя по всему Интернету. Кроме того, это позволяет встроенному сайту делать выводы о конкретных состояниях пользователя на сайте верхнего уровня с использованием методов сторонних каналов, таких как атаки по времени , XS-утечки и COSI .

Исторически хранилище было зашифровано только по источнику. Это означает, что если iframe из example.com встроен в a.com и b.com , он может узнать о ваших привычках просмотра для этих двух сайтов, сохранив и успешно извлекая идентификатор из хранилища. При включенном сторонних разделах хранилища хранилище для example.com существует в двух разных разделах, один для a.com и другой для b.com .

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

До

API-интерфейсы хранения без разбиения на разделы.
До разбиения хранилища на разделы example.com мог записывать данные при внедрении в a.com, а затем считывать их при внедрении в b.com.

После

API-интерфейсы хранения с разделением.
После разбиения хранилища example.com, встроенный в b.com, не сможет получить доступ к хранилищу example.com, встроенному в a.com.

Разделение хранилища на связанных iframe-ах

Сложность разбиения хранилища на разделы значительно возрастает, когда элементы iframe вложены друг в друга, особенно когда один и тот же источник встречается в цепочке несколько раз.

Например, A1 содержит iframe для B, который содержит iframe для A2, и оба A1 и A2 находятся на одном сайте. Если бы при разбиении учитывались только сайт верхнего уровня и источник текущего фрейма, iframe A2 мог бы ошибочно рассматриваться как «первичный», поскольку он разделяет сайт с верхним уровнем (A1), несмотря на кросс-сайтовый iframe B между ними. Это могло бы открыть A2 для рисков безопасности, таких как clickjacking, если бы A2 имел доступ к неразмеченному хранилищу по умолчанию.

Чтобы решить эту проблему, Chrome добавляет «бит предка» к ключу раздела хранилища. Этот бит устанавливается, если какой-либо документ между текущим iframe и сайтом верхнего уровня имеет другое (межсайтовое) происхождение. В этом случае сайт B является межсайтовым, поэтому бит будет установлен для A2, а его хранилище будет разделено с A1.

Когда цепочка iframe состоит исключительно из контекстов одного и того же сайта (например, Сайт A1, содержащий A2, который затем содержит A3), бит предка не будет далее разделять их хранилище. В таких случаях их хранилище остается общим, ключом которого является их общее происхождение и сайт верхнего уровня.

Для сайтов, которым требуется неразделенный доступ через цепочку iframes, Chrome экспериментирует с расширением Storage Access API для включения этого варианта использования . Поскольку Storage Access API требует, чтобы фреймовый сайт явно вызывал API, это снижает риск кликджекинга.

Изменения API из-за разбиения на разделы

API, затронутые разделением, можно разделить на следующие группы:

API-интерфейсы хранения

  • Система квот
    Система квот используется для определения того, сколько дискового пространства выделяется для хранения. Система квот управляет каждым разделом как отдельным контейнером, чтобы определить, сколько места разрешено и когда оно очищается.
    Метод navigator.storage.estimate() теперь предоставляет информацию, специфичную для раздела хранилища. API только для Chrome, такие как window.webkitStorageInfo и navigator.webkitTemporaryStorage , устарели.
    Хранилища IndexedDB и Cache используют секционированную систему квот.
  • API веб-хранилища
    API веб-хранилища предоставляет механизмы, с помощью которых браузеры могут хранить пары ключ-значение. Существует два механизма: локальное хранилище и хранилище сеансов . Они не управляются квотами, но все еще разделены.
  • Частная файловая система Origin
    API доступа к файловой системе позволяет сайту читать или сохранять изменения непосредственно в файлах и папках на устройстве после того, как пользователь предоставил доступ. Частная файловая система Origin позволяет источнику сохранять личный контент непосредственно на диске. Этот контент остается доступным пользователю, но теперь он разделен.
  • API хранилища
    API Storage Bucket разрабатывается для Storage Standard , который объединяет различные API хранения, такие как IndexedDB и localStorage, используя новую концепцию, называемую buckets. Данные, хранящиеся в buckets, и метаданные, связанные с buckets, разделяются.
  • Заголовок Clear-Site-Data
    Включение заголовка Clear-Site-Data в ответ позволяет серверу запросить очистку данных, хранящихся в браузере пользователя. Кэш, файлы cookie и хранилище DOM могут быть очищены. Использование заголовка очищает хранилище только в пределах одного раздела.
  • Хранилище URL-адресов BLOB-объектов
    URL-адрес BLOB-объекта предоставляет доступ к BLOB -объекту, содержащему необработанные данные. Без разделения хранилища URL-адрес BLOB-объекта, сгенерированный в стороннем iframe на одном сайте, может использоваться в iframe того же источника, встроенном в другой сайт. Например, если iframe example.com встроены как в a.com , так и b.com , URL-адрес BLOB-объекта, сгенерированный в iframe, встроенном в a.com , может быть передан и затем использован iframe, встроенным в b.com без каких-либо ограничений. Начиная с Chrome 137 (выпущенного 27 мая 2025 г.), URL-адреса BLOB-объектов разделяются для всех видов использования, за исключением навигации верхнего уровня. Случаи, которые теперь будут блокироваться, включают случаи, когда URL-адреса BLOB-объектов между разделами используются с fetch() или в качестве значения атрибута src для различных элементов HTML. Навигации верхнего уровня, такие как вызов window.open() или нажатие ссылки с target='_blank' , на URL-адреса Blob не будут заблокированы, если они являются кросс-секционными, но noopener будет применен, если сайт URL-адреса Blob является кросс-сайтовым с сайта верхнего уровня страницы, инициирующей навигацию. Принудительное применение noopener означает, что документ, инициирующий навигацию, не сможет получить дескриптор окна для документа URL-адреса Blob, который он открыл. В предыдущем примере разделение не позволит iframe на b.com извлечь содержимое URL-адреса Blob, но он все равно сможет выполнить window.open() для него.

API-интерфейсы связи

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

Из-за разделения следующие коммуникационные API не позволяют сторонним iframe обмениваться данными с контекстами того же источника:

  • Канал вещания
    API Broadcast Channel обеспечивает связь между контекстами просмотра (окнами, вкладками или фреймами) и работниками одного и того же источника.
    Поведение межсайтового iframe postMessage() менять не предлагается, поскольку взаимосвязь между этими контекстами уже четко определена.
  • SharedWorker
    API SharedWorker предоставляет обработчик, к которому можно получить доступ из контекстов просмотра одного и того же источника.
  • Веб-замки
    API Web Locks позволяет коду, работающему на одной вкладке или в одном и том же рабочем процессе, получать блокировку для общего ресурса во время выполнения какой-либо работы.

API сервисного работника

API Service Worker позволяет сайтам выполнять задачи в фоновом режиме. Сайты регистрируют service worker, которые создают новые worker contexts для реагирования на события. Традиционно эти worker могли бы взаимодействовать с любым контекстом того же происхождения. Однако, поскольку service worker могут изменять время навигационных запросов, они представляют риск межсайтовых утечек информации, таких как перехват истории .

По этой причине Service Workers, зарегистрированные из стороннего контекста, теперь разделены.

API расширения

Расширения — это программы, которые позволяют пользователям настраивать свой браузер.

Расширенные страницы (страницы со схемой chrome-extension:// ) могут быть встроены в сайты по всему Интернету. В этом сценарии страницы расширения продолжают иметь доступ к своему разделу верхнего уровня. Расширения также могут встраивать другие сайты; когда они это делают, эти встроенные сайты будут получать доступ к своему разделу верхнего уровня, при условии, что у расширения есть разрешения хоста для них.

Более подробную информацию см. в документации по расширению .

Демонстрация: тестирование разбиения хранилища на разделы

Демонстрационный сайт: https://storage-partitioning-demo-site-a.glitch.me/

Демонстрационный сайт с зелеными галочками слева и красными крестиками справа.
Скриншот демонстрации, показывающий вывод для браузера с разделением хранилища слева и без разделения хранилища справа.

В демоверсии используются два сайта: сайт A и сайт B.

  • Когда вы посещаете сайт А в контексте верхнего уровня, он устанавливает данные, используя различные методы хранения.
  • Сайт B встраивает страницу с сайта A, и эта встройка пытается прочитать параметры хранения, заданные ранее.
  • Когда сайт A встроен в сайт B, у него нет доступа к этим данным, когда хранилище разделено, и поэтому чтение завершается неудачей.
  • Демонстрация использует успешность или неудачу каждого чтения, чтобы показать, разделены ли данные.

На данный момент вы можете отключить разбиение хранилища в Chrome с помощью параметра командной строки --disable-features=ThirdPartyStoragePartitioning . Примечание: этот параметр командной строки предназначен для целей разработки и тестирования и может быть удален или изменен в будущих версиях Chrome.

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

Привлекайте и делитесь отзывами