Перейти к содержанию

IPFS: поддомены, origin и активный контент

Проверенный выпуск может содержать JavaScript. Когда браузер исполняет его, права определяются origin — сочетанием схемы, хоста и порта. В уроке разберём, почему два CID в разных путях одного шлюза не обязательно изолированы как два сайта, и как поддоменная выдача помогает выразить границу выпусков.

Мы не поднимаем шлюз, не меняем DNS и не открываем активное содержимое. URL ниже используют зарезервированное объясняющее имя gateway.example и метки CID. Они не являются ссылками на работающую инфраструктуру библиотеки.

Общий хост

На path-шлюзе страницы могут иметь такие адреса:

https://gateway.example/ipfs/ROOT_A/index.html
https://gateway.example/ipfs/ROOT_B/index.html

Пути различаются, но origin совпадает. Для браузерной модели они не становятся независимыми сайтами только потому, что значения CID разные. Это существенно для доступного хранилища и взаимодействия активного кода в разрешённых правилами случаях.

Если шлюз обслуживает произвольный сторонний HTML под общим хостом, библиотека не должна размещать там административные функции, полагаясь на отличие пути. Активный код и сеансовые данные требуют отдельной изоляции. Проверка содержания по CID говорит, какой именно код получен, но не говорит, какие полномочия ему разумно дать.

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

Корень в поддомене

Поддоменная форма переносит корень в hostname:

https://ROOT_A.ipfs.gateway.example/index.html
https://ROOT_B.ipfs.gateway.example/index.html

Здесь показана схема, а не допустимые реальные метки DNS: ROOT_A должен быть заменён поддерживаемой формой CID. Хосты различаются, следовательно, отличаются origin. Файлы одного корня могут взаимодействовать внутри общего контекста этого выпуска, а другой корень получает свой контекст.

Спецификация использует подходящее регистронезависимое кодирование и ограничения DNS-метки. Поэтому нельзя вставить произвольную длинную CID-строку в hostname без проверки. Совместимый шлюз преобразует поддерживаемые формы по установленным правилам.

Это улучшает соответствие обычной модели браузера. Однако parent-domain, cookies и настройки инфраструктуры также важны. Оператор должен соблюдать рекомендации по Public Suffix List и изоляции. Поддомены сами по себе не являются универсальным доказательством защиты всех веб-механизмов.

Ссылки внутри выпуска

При поддоменной выдаче корень URL / относится к выбранному содержимому этого hostname. Это делает обычные относительные пути понятнее, чем префикс каталога на path-шлюзе. Но файл всё ещё должен иметь правильные внутренние связи.

Ссылка на /assets/site.css в поддоменном выпуске может вести к ресурсу собственного корня. На path-шлюзе тот же путь мог вести к корню оператора. Поэтому один и тот же HTML требует заранее выбранного профиля выдачи либо переносимых относительных путей, как мы подготовили раньше.

Перенаправление path → subdomain может сохранить путь и параметры по спецификации. Клиент должен корректно обрабатывать поддерживаемый redirect, а не считать отсутствие непосредственного 200 окончательной ошибкой. При этом адрес конечного объекта остаётся проверяемым.

Кабинет на основном сайте

Личный кабинет и оплату библиотеки сохраняем на отдельном доверенном origin. Публичный архив не получает cookie административной сессии. Если требуется взаимодействие, оно проходит через явно разрешённый прикладной API с собственной авторизацией.

Не отправляем учётный токен в любой hostname, который пользователь назвал «шлюзом». Список источников задаёт конфигурация. Для публичного чтения большинства файлов вообще не нужен секрет сессии. Подключение кошелька также не требуется для просмотра HTML-урока.

Если API допускает CORS, разрешения выбираются по реальным origin и назначению. Разрешение всех источников не следует из слова Web3. Объявление корня в контракте подтверждает содержание выпуска, но не даёт ему административную роль в библиотеке.

Хранилище и офлайн-копии

Разные CID-поддомены могут иметь разные браузерные хранилища. Это удобно для изоляции, но означает, что локальная копия первой редакции не обязана автоматически появиться в контексте второй. Интерфейс должен объяснять, какой выпуск сохранён и где.

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

Service Worker также связан со своим scope и origin. Нельзя обещать, что один работник общего path-шлюза безопасно обслуживает любой сторонний архив. Этот механизм должен принадлежать контролируемому приложению и быть описан отдельно.

Разные поддомены и общие cookies

Разделение выпусков по origin решает важную часть изоляции, но оператор должен исследовать также поведение своего домена. Cookie, установленная с слишком широким атрибутом Domain, способна быть отправлена подходящим поддоменам. Поэтому нельзя размещать недоверенные активные выпуски под административным доменом и считать разное имя хоста единственной защитой. Вопросы cookies, доменной политики и управления шлюзом требуют согласованной конфигурации.

Для библиотеки личный кабинет и платёжный интерфейс имеют собственное доверенное размещение. Учебные HTML-материалы не получают его сессионные полномочия. Настройки cookies и обмен данными определяются явно; файл курса не должен использовать случайное наследование административного контекста. Рекомендации оператора шлюза учитывают и регистрацию доменов в механизмах Public Suffix, где это применимо, но такое решение не заменяет проектирования сессий самого сайта.

Разные CID-поддомены означают также разные пространства обычного браузерного хранения по origin. Первая редакция не обязана видеть IndexedDB второй. Это полезная граница, однако интерфейс офлайн-чтения должен учитывать её заранее. Если библиотека хочет единый управляемый читатель с общей описью, такой читатель может получать проверенные данные в своём контексте, не исполняя произвольный HTML выпуска рядом с личными данными. Это отдельная архитектура, а не свойство одной строки URL.

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

Неизменность не равна безопасному исполнению

CID позволяет обнаружить подмену известных байтов. Если известные байты сами содержат опасный скрипт, проверка успешно подтвердит его. Поэтому безопасный выпуск требует редакционного контроля зависимостей, допустимых операций и способов отображения.

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

В досье сохраняем форму шлюза, правила origin, допустимые активные ресурсы и связь с основным сайтом. Сейчас эти настройки подготовлены, но не применены и не проверены в браузере. Нельзя выдать диаграмму за проведённый аудит инфраструктуры.

Полные правила доступны в Subdomain Gateway Specification и рекомендациях оператора. Результат урока — конкретная граница браузерных полномочий. Следующий шаг добавит проверку блоков через trustless-ответы, сохранив эту границу исполнения.

Оглавление серии