Назад в Центр знаний
Платформа

Вход Web Share Target PWA и конфиденциальность

Спроектируйте Web Share Target PWA с проверкой GET и POST, ограниченным хранением и безопасным запасным сценарием.

BotBrowser Team

Документация

Нужна структурированная документация по теме Платформа?

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

Web Share Target PWA получает опосредованный браузером запрос на передачу данных, но не знает, почему человек выбрал источник и предназначалось ли каждое поле для выхода из него. BotBrowser может воспроизвести собственный fixture и проверить маршрут, состояние проверки и запасной путь; он не выбирает источник операционной системы и не подтверждает решение человека о раскрытии данных.

Вход share_target разделён на разбор GET или POST, проверку service worker и границу конфиденциальности

TL;DR

  • Считайте share_target недоверенным контрактом входа, а не сигналом личности.
  • Проверяйте параметры GET и форму POST до отображения или сохранения.
  • Делайте scope, маршрут и разрешённые поля манифеста узкими.
  • Делайте повторные доставки идемпотентными и храните только необходимый минимум.
  • Оставляйте обычную навигацию или копирование, если браузер не устанавливает или не вызывает PWA.

Содержание

Манифест и разбор запроса

Предложение Web Share Target от WICG определяет поле share_target манифеста, которое сопоставляет входящие данные с URL, методом и именами параметров. Справочник MDN Web Share Target API описывает передачу в установленную PWA. Это объявление не является токеном аутентификации, личностью отправителя или гарантией безопасного хранения общих данных. Для отдельного локального статуса см. границы Badging API для уведомлений PWA.

BotBrowser может воспроизвести авторизованный fixture того же origin и проверить видимый маршрут, состояние проверки и запасной путь. Он не выбирает источник операционной системы и не подтверждает, что именно человек решил раскрыть; эти ограничения должны быть частью продуктового контракта.

Держите объявление явным и небольшим. Публичная цель только с URL может выглядеть так:

{
  "share_target": {
    "action": "/inbox/share",
    "method": "GET",
    "params": { "title": "title", "text": "text", "url": "url" }
  },
  "acceptanceMetadata": { "fixtureRevision": 3 }
}

action должен находиться внутри области приложения. Узкий маршрут inbox лучше универсального обработчика. Модель хранилища браузера помогает разделить состояния origin вместо непрозрачного архива профиля PWA.

GET помещает сопоставленные значения в URL действия. URL может попасть в историю, журналы, referrer, снимки и аналитику, поэтому не добавляйте туда bearer-токены, частный текст или идентификаторы аккаунта. Нормализуйте длину и кодировку до первого рендера.

POST скрывает тело из URL, но всё равно пересекает границу браузера и приложения. Манифест может объявить application/x-www-form-urlencoded или multipart/form-data; получатель должен отклонить неожиданный тип и ограничить тело до разбора. Для файлов нужны отдельные лимиты размера, типа и вредоносного содержимого. Успешный разбор не разрешает сохранять исходное тело.

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

{
  "method": "POST",
  "route": "/inbox/share",
  "fields": ["title", "text", "url"],
  "bodyBytes": 4096,
  "outcome": "validated-local-draft",
  "fixtureRevision": 3
}

Поле share_target манифеста в MDN описывает форму и отображение параметров. Сохраняйте одинаковое отображение в манифесте, парсере и тестах: молча опустевший url означает потерю данных.

Проверка, приватность и запасной путь

Служебный worker может получить навигацию и направить её управляемому клиенту, либо страница обработает запрос после перехода. В обоих случаях проверяйте origin, метод, тип содержимого, длину полей и схему URL до показа данных. Отклоняйте javascript: и неожиданные встроенные учётные данные.

Не выводите отправителя из Referer, user-agent или времени: эти значения неполны и могут отсутствовать. Регистрация worker также не доказывает, что текущая страница управляется им; проверяйте видимый маршрут и маркер версии приложения. Жизненный цикл кеша worker и приватность показывает, почему старый worker способен вернуть старый ответ.

Считайте устаревший worker ограниченной ошибкой. Показывайте значения только после проверки, сохраняйте исходный маршрут при ошибке разбора и предлагайте повтор или копирование. Не отправляйте неудачный POST обратно без ключа идемпотентности.

Источник может повторить запрос после тайм-аута, а человек может вызвать одну цель дважды. Создайте собственный идентификатор запроса, удаляйте дубликаты в коротком окне и записывайте только состояние вроде accepted, rejected или expired. Если хватает непрозрачного идентификатора fixture, не журналируйте текст, байты файла или полный URL.

Храните частные данные локально, пока человек не подтвердит следующий шаг. Кнопка сохранения может создать серверную запись со своими правами и сроком хранения; простое открытие цели не должно этого делать. Удаляйте временные данные после принятия или отмены видимого черновика. Кеш worker не должен стать случайным архивом.

Браузерная передача не создаёт связь аккаунтов. Приглашение коллеги должно быть отдельной подтверждённой и аудируемой операцией. Share target является удобным входом, а не решением контроля доступа. Границы разрешений Web Share отделяют запрос передачи от подтверждения доставки. Руководство Web Share API и обмен по действию пользователя добавляет ограничения активации и отмены, которые действуют до получения данных.

Именно для Web Share Target BotBrowser может воспроизвести авторизованный fixture и проверить видимый маршрут входа, результат проверки и запасной путь. Он не выбирает реальный источник операционной системы и не доказывает, что именно раскрыл человек, поэтому это проверка интерфейса и запроса, а не сертификация приватности.

Проверьте синтетические запросы GET и POST, слишком большое тело, неизвестное поле, неверный URL, повторный идентификатор и отсутствие worker. Проверяйте видимые состояния и ограниченную запись, а не системный chooser. Fixture может подтвердить лимит 4096 байт, но не предсказывает содержимое настоящего источника.

Оставьте навигацию /inbox/share, копирование ссылки или поле вставки, если нет установки, манифеста или поддержки. Запасной путь должен сохранить задачу, не импортируя те же данные через более широкую трассу. Руководство MDN по обмену данными между приложениями описывает пользовательскую связь, но не заменяет проверку хранения.

Реализация и приёмка

Манифест является конфигурацией, а не парсером. Прочитайте его член share_target на этапе сборки, отклоните action вне области приложения и создайте список разрешённых значений для сравнения runtime с входящим запросом. Полезный артефакт проверки содержит action, method, enctype и каждое имя параметра. В нём также нужна ревизия манифеста: worker и страница могут обновляться в разное время. Запрос, обработанный ревизией 2, нельзя молча сравнивать с ожиданием, записанным для ревизии 3.

Для цели GET создайте URL из URL запроса и читайте только объявленные ключи. URLSearchParams.get() возвращает первое значение, а getAll() позволяет проверить повторяющиеся ключи. Решите, отклонять ли повторы или сводить их к одному значению; не передавайте это решение настройкам framework. Декодируйте percent-escape один раз, превращайте неверный UTF-8 в отказ, обрезайте только по правилам поля и проверяйте лимиты после декодирования. Например, лимит заголовка 120 скалярных значений Unicode и текста 4 000 значений проверяйте до рендеринга, а не после усечения колонкой базы данных.

Сам URL чувствителен, даже когда значения выглядят безобидно. Reverse proxy может записать полный путь, история браузера может синхронизировать его, referrer может раскрыть его другому origin, а снимок или событие аналитики может его захватить. Задайте подходящую Referrer-Policy, удаляйте query string редиректом того же origin после создания проверенного черновика и убедитесь, что редирект не превращает отказ в принятие. Редирект очищает данные, но не авторизует.

Для POST сначала проверьте request.method, заголовок Content-Type и объявленный enctype. Разбирайте application/x-www-form-urlencoded с максимумом байт и полей. Для multipart/form-data требуйте boundary, отклоняйте вложенные multipart-части без явной поддержки и ограничивайте общий размер и каждую часть. Проверяйте Content-Length, если он есть, но всё равно применяйте потоковый лимит: chunked-запросы не имеют надёжной объявленной длины. Немедленно прерывайте чтение тела при превышении и возвращайте стабильный 413 или видимое состояние too-large.

Пример задаёт только границу парсера. В production всё ещё нужны потоковая реализация, multipart-библиотека с явным лимитом и отображение ошибок, никогда не отражающее тело. Не показывайте сообщение исключения со значением поля. Парсер, принимающий неизвестное поле admin, redirect или callback, расширяет контракт, даже если приложение позднее его игнорирует; отклоняйте неизвестные имена до бизнес-логики.

У поля url есть отдельная политика. Разберите его как URL, требуйте https: или явно проверенное исключение http:, отклоняйте компоненты имени пользователя и пароля и решите, удалять ли fragment. URL того же share endpoint может создать цикл редиректов, а data: URL способен содержать мегабайты кодированного содержимого. Если продукт принимает только публичные ссылки, отклоняйте имена хостов приватных сетей на границе сервера и опасные схемы на странице. Это проверка входа, а не утверждение о безопасности назначения ссылки.

Файлы, повторы и CSRF. multipart/form-data может передать файл, даже если видимый продукт просит только заголовок и URL. Задайте отдельные allow-list файлов, максимум размера и количества. Используйте объявленный MIME для маршрутизации, затем проверяйте magic bytes в карантине: заголовок задаёт отправитель. Для небольшого image fixture политика может разрешить image/png и image/jpeg до 2 MiB, один файл и лимит декодированных пикселей. Отклоняйте архивы, скрипты и polyglot-файлы без отдельного одобрения. Не записывайте временный путь загруженного файла в журнал приёмки. Храните байты файла в коротком карантине, принадлежащем запросу, а не в кеше воркера или общей базе браузера. Сканируйте или обрабатывайте до подтверждённого сохранения, отделяйте временное имя от исходного и удаляйте при отмене, тайм-ауте, ошибке разбора и истечении срока. Успешная MIME-проверка не является поиском вредоносного кода, а локальный черновик не означает согласия на загрузку. Если среда не может проверить файл, показывайте file-review-unavailable и сохраняйте запасной путь вместо молчаливого принятия.

Web Share Target принимает навигационный вход, поэтому обычные предположения о CSRF сохраняются. Запрос того же origin может нести ambient cookies, а маршрут можно открыть вне системного share sheet. Требуйте сессию приложения, короткоживущий CSRF-токен для изменения состояния или явное подтверждение перед серверным сохранением. Наличие share_target не доказывает вызов маршрута через sharing. Маршрут должен быть безопасен при вставке в адресную строку и при открытии обычной ссылкой.

Idempotency key не даёт повтору создать два черновика, но не аутентифицирует отправителя. Сгенерируйте случайный идентификатор на границе приложения, свяжите его с текущей сессией и ревизией манифеста и истекайте его в коротком документированном окне. Если тот же key пришёл с другими деталями метода или другой сессией, классифицируйте его как key-conflict и не объединяйте записи. Идентичный повтор может вернуть исходный ограниченный результат, например accepted-local, duplicate или expired, без исходных приватных полей.

Не используйте одни часы как ключ повтора. Расхождение времени, задержка доставки и два законных обмена в одну секунду делают его неоднозначным. Не выводите маркер повтора из исходного текста, называя его анонимным: короткий заголовок или URL можно угадать и сравнить. Предпочитайте непрозрачный ID fixture в журналах, а записи сравнения храните коротко и с контролем доступа. Граница приватности включает телеметрию, отчёты о сбоях, воспроизведение сессий, тела запросов в очередях и выгрузки поддержки, а не только основную базу.

Записи приёмки. Такая запись полезна, когда позволяет воспроизвести видимую ветку без хранения переданного материала. Включите ревизию fixture, метки браузера и ОС, маршрут, метод, объявленный enctype, число байт, принятые имена полей, результат проверки, классификацию повтора, состояние запасного пути и срок удаления. Исключите текст заголовка, значения URL, имена и байты файлов, cookies, заголовки авторизации и полный query string. Стабильную запись можно сравнивать между версиями браузера, не превращая её в архив содержимого.

{
  "fixtureRevision": 3,
  "route": "/inbox/share",
  "method": "POST",
  "enctype": "multipart/form-data",
  "bodyBytes": 4096,
  "fields": ["title", "text", "url"],
  "fileCount": 0,
  "validation": "accepted-local",
  "replay": "new",
  "csrf": "confirmed",
  "retention": "delete-after-cancel"
}

Таблица решений делает контракт проверяемым:

ГраницаЧто устанавливает результатБезопасное следующее действие
Неподдержанный манифест или цель не установленаБраузер не может вызвать этот входОставить обычную навигацию и вставку
GET с повторным или слишком большим полемКонтракт URL недействителенУдалить запрос, показать ограниченную ошибку, не хранить
POST с неожиданным MIMEКонтракт тела не выполненОстановить разбор и вернуть content-type-rejected
Файл превышает лимитПолитика файла нарушенаУдалить временную часть и показать правило размера
Поля верны, но подтверждения нетМожно показать локальный черновикОставить локально, не создавать серверную запись
Тот же idempotency key и те же деталиЗамечена повторная доставкаВернуть прежний общий результат без тела запроса
Тот же key, но детали или сессия отличаютсяВозник конфликт повтораОтклонить, кратко предупредить и потребовать новое действие
Worker отсутствует или устарелПредусмотренный маршрут недоступенСохранить маршрут и предложить копирование или повтор

Таблица отделяет то, что устанавливает наблюдение браузера, от желаемых утверждений продукта. Видимое состояние accepted-local доказывает, что этот fixture прошёл проверки страницы. Оно не доказывает, что источник отправил только эти поля, что человек намеревался раскрыть каждое значение или что последующее серверное сохранение соблюдает заявленный срок хранения.

Возможности и ограничения BotBrowser. Для этой темы Web Share Target BotBrowser может воспроизвести авторизованный fixture того же origin для GET или POST, проверить маршрут манифеста, выполнить валидацию воркера и проверить видимые состояния accepted, rejected, duplicate, oversized, missing-worker и запасного пути. Документация платформы BotBrowser описывает границу управляемого браузера. BotBrowser не может открыть системный chooser, выбрать реальное приложение-источник, наблюдать решение человека о раскрытии, сканировать внешнюю файловую цепочку или подтвердить удаление сервером вне fixture.

Фиксируйте узкий явный результат: accepted-local, duplicate, rawContentKept=false, osShareSource=not-observed и serverRetention=not-certified, а не утверждение, что системный chooser или удаление на сервере были наблюдены.

Повторяйте тот же fixture после изменения одной переменной: action, scope, разрешённых полей, enctype, лимита тела, версии воркера, окна идемпотентности или маршрута запасного пути. Сравнивайте первое видимое расхождение. Успех в управляемом контексте подтверждает контракт страницы и запроса, но не универсальную совместимость с каждой системной поверхностью и не сертификацию приватности.

Источники

Итог

Объявите узкий share_target, разбирайте GET и POST одинаковыми правилами и отделяйте принятие от сохранения. Идемпотентный fixture и видимый запасной путь делают различия браузеров проверяемыми, не превращая опосредованную передачу в личность или доказательство доставки. Повторяйте fixture после изменения манифеста, worker, полей или политики хранения.

#Web Share Target#PWA#Конфиденциальность#Service Worker#BotBrowser

Эта статья входит в руководство: Поверхности веб-платформы: карта проверки

Переведите BotBrowser из исследований в продакшн

Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.