Безопасность и Content Security Policy
Какие директивы CSP нужны виджету, почему он работает без встроенного скрипта и unsafe-inline, как изолирован от страницы и каким секретам никогда не место в браузере.
Content Security Policy
Виджет не загружает сторонние шрифты и пиксели отслеживания, не выполняет eval. Стили задаются создаваемыми таблицами стилей (adoptedStyleSheets) в shadow DOM; на них style-src не распространяется. Поэтому unsafe-inline и unsafe-eval не нужны.
С адресами reactive.chat:
Content-Security-Policy:
script-src 'self' https://cdn.reactive.chat;
connect-src 'self' wss://ws.reactive.chat https://ws.reactive.chat;
img-src 'self' data: https:;
Content-Security-Policy:
script-src 'self' https://chat.your-company.com;
connect-src 'self' wss://chat.your-company.com https://chat.your-company.com;
img-src 'self' data: https:;
Отдельные директивы:
- script-src — расположение
loader.js. Ядро (core.<hash>.js) и поздние модули (туры, текст о конфиденциальности, магазин) тоже приходят оттуда. - connect-src с wss:// — подключение чата.
- connect-src с https:// — тот же адрес ещё раз: через него работают резервный HTTP, офлайн-форма, загрузки, текст о конфиденциальности и Smart Answer. Без директивы это заметно лишь в сетях без WebSocket, где подключения вообще не будет.
- img-src — изображения в чате: логотип и аватары (ваши
https://адреса илиdata:изображения), промокарточка и предпросмотры вложений (с адреса чата). При суженииimg-srcвключите как минимум адрес чата и хосты логотипа и карточек. Заблокированное изображение виджет показывает строкой файла вместо предпросмотра.
Старые браузеры без создаваемых таблиц стилей (например, Safari до 16.4) используют <style>, который строгая style-src блокирует. Виджет работает, но без оформления.
Встроенный скрипт не нужен
Установка состоит только из <script src> с атрибутами. Свои вызовы (identify, track, open) размещайте в файлах скриптов или встроенном скрипте с nonce:
<script nonce="R4nd0mN0nc3">
ReactiveChat('identify', { userId: '4711', userHash: '…', exp: 1792503600 });
</script>
Шаблон без встроенного скрипта: Идентификация посетителей.
Subresource Integrity
У loader.js нет номера версии в имени, он постоянно обновляется; атрибут integrity отключит чат при следующем обновлении. Ядро загружается с хешем содержимого в имени (Архитектура). Если политика требует SRI, предоставляйте loader.js сами и задайте data-rc-ws-url (Быстрый старт); обновление тогда тоже ваша задача.
Изоляция от страницы
- Закрытый shadow DOM. Стили страницы не проникают в виджет, стили виджета — на страницу, даже с глобальными сбросами.
- Без cookie. Виджет не устанавливает cookie; ID в хранилище браузера, без согласия только в
sessionStorage(Интеграция конфиденциальности). - Нет доступа к полям форм. Текст страницы для ассистента никогда не читает поля ввода и вообще не собирается на страницах вроде аккаунта, оплаты, корзины. Другие участки исключаются через
data-rc-private. - Персональные данные маскируются дважды: в браузере перед отправкой (карты с проверкой Луна, IBAN, почта, телефон, налоговые номера) и на сервере до хранения. Чувствительные параметры (
email,password,token,key,card…) удаляются из передаваемых адресов. - Ссылки и изображения сообщений и карточек ограничены
https://; ссылкиjavascript:иdata:отбрасываются.
Проверка источника
Подключение чата принимается только с доменов проекта в Разрешённых источниках (с поддоменами). Сторонняя страница, скопировавшая ключ сайта, получает origin_denied. Если список пуст, проверки нет; всегда вводите домены. Подробнее: Транспорт.
Сам ключ сайта не секрет: находится в исходном коде каждой страницы.
Чему никогда не место в браузере
- Секрету идентификации (для
userHash) — Идентификация - Секрету конечной точки данных клиентов
rckd_…— Данные клиентов - Секрету подписи вебхуков — Вебхуки
- API-ключам
rc_live_…— Серверный API - Ключу прокси
rcpx_…— Собственный домен
Также не в приложении, публичном репозитории или адресе страницы.
Защита от злоупотреблений
Сервер ограничивает подключения, кадры и сообщения на соединение и адрес и блокирует при повторных нарушениях (закрытие 1008). За собственным прокси считает по адресу посетителя, только если ключ прокси правильный; иначе все делят адрес прокси. Значения: Ограничения и квоты.
Далее: Собственный домен
Обновлено: