К содержанию
ActionPulse

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

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

Кому
Безопасникам и тем, кто решает, включать ли записи
Проверено
На этой странице

Запись сессии — единственная часть ActionPulse, которая переносит на сервер разметку вашей страницы, а не только имена событий и свойства. Поэтому решение «включать или нет» принимается отдельно от решения «подключать аналитику». Эта страница отвечает на вопросы, которые задаёт безопасник: что физически попадёт в хранилище, чем это ограничено в коде, кто получит доступ, что останется в журналах и что удалится по запросу человека.

Операционная часть — как найти запись, что показывает плеер, как включить сбор — в записях сессий.

Что попадает в запись

Запись — это не видеофайл и не снимки экрана. Трекер отправляет поток изменений разметки, а плеер собирает страницу заново. Практическое следствие: в запись попадает ровно то, что есть в DOM, и ничего из того, чего в DOM нет.

Что попадает:

  • структура разметки — теги, их вложенность, классы и идентификаторы;
  • видимый текст страницы — только если стандартный режим текста разрешён и проектом, и самой интеграцией (см. следующий раздел);
  • значения обычных атрибутов разметки, включая ваши собственные data-*;
  • перемещения курсора и прокрутка, прореженные до одного замера в 50 мс и 150 мс соответственно;
  • факты кликов и изменений разметки во времени.

Что не попадает никогда — это зашито в конфигурацию записи и не настраивается:

Не записывается Как это обеспечено
Значения полей ввода маскируются всегда, на любом тарифе и в любом режиме текста
Пароли маскируются безусловно, отдельным правилом поверх общего
Содержимое canvas запись canvas выключена
Встроенные изображения вставка изображений в запись выключена
Шрифты сбор шрифтов выключен
Кросс-доменные фреймы запись сторонних iframe выключена
Консоль браузера и сетевые запросы плагины записи не подключены вовсе
Адреса внешних ресурсов заменяются пустым адресом (см. ниже)
Стили и CSS вырезаются вместе с style и правилами CSS

Дополнительно каждое событие записи проходит через фильтр приватности до сжатия и отправки:

  • значения атрибутов, чьи имена похожи на секрет или прямой идентификатор (token, secret, password, authorization, cookie, session, email, phone и родственные), заменяются на [redacted];
  • обработчики событий (onclick и подобные), srcdoc, content, style и текст CSS обнуляются;
  • сетевые атрибуты (src, srcset, href, action, poster, cite и прочие) заменяются на пустой адрес; сохраняются только ссылки-якоря вида #section внутри страницы;
  • любая строка, в которой есть ссылка на ресурс, обнуляется целиком;
  • строки, похожие на адрес электронной почты, российский телефон, номер паспорта, ключ ActionPulse или JWT, заменяются на [redacted].

Маркеры на таймлайне — pp.rage_click, pp.dead_click, pp.js_error — добавляются в запись с пустым содержимым. В тело записи не переносятся ни селектор, ни адрес страницы, ни текст ошибки: в запись попадает только факт, что в этот момент произошло событие с таким именем.

Поля ввода и текст страницы

Разделите два независимых механизма — их часто путают.

Поля ввода. Маскирование всех полей ввода включено всегда и не отключается ничем: ни настройкой проекта, ни тарифом, ни параметром вызова. Пароли маскируются отдельным безусловным правилом. То есть даже в самом «открытом» режиме то, что человек печатает, в записи не видно.

Остальной текст страницы. Здесь работают два независимых переключателя, и применяется более строгий из них:

  1. настройка проекта Настройки → Сбор и приватность → Записи сессий → «Текст на странице»;
  2. режим, заданный самой интеграцией в браузере.
Режим Что в записи По умолчанию
Строгий — маскировать весь текст текста страницы нет вообще: видна структура и поведение да
Стандартный — маскировать ввод и пароли текст виден; поля ввода по-прежнему замаскированы нет

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

Отдельного атрибута для маскирования фрагмента — вида data-pp-mask — в продукте нет. Если нужно скрыть конкретный блок, а остальной текст оставить видимым, блок исключается целиком, см. следующий раздел.

Как исключить область страницы

Из записи исключает только атрибут data-pp-block. Он убирает элемент и всё его поддерево: в записи не будет ни содержимого, ни разметки внутри.

Атрибут Автосбор поведения Записи сессий
data-pp-block исключает элемент и всё внутри исключает элемент и всё внутри
data-pp-ignore исключает элемент и всё внутри не влияет
<!-- В запись не попадёт ничего: ни текст, ни разметка -->
<section data-pp-block>
  <h3>Медицинская карта</h3>
  <p>Диагноз: …</p>
  <img src="/scans/12345.png" alt="Снимок" />
</section>

<!-- Уйдёт из отчёта «Поведение», но в записи останется видно -->
<div data-pp-ignore>
  <button>Служебная кнопка</button>
</div>

Атрибут ставится на контейнер, а не на каждый элемент внутри: правило наследуется на всё поддерево. Поэтому размечать удобнее один раз — на уровне компонента, который отвечает за чувствительную область.

Кто может смотреть и что остаётся в аудите

Список сессий и плеер требуют роли «Аналитик» или выше; «Наблюдателю» раздел закрыт. Оба запроса привязаны к проекту: обращение к проекту чужой организации отвечает 404, а не 403, чтобы по ответу нельзя было проверять существование чужих объектов. Чтение ограничено 120 запросами в минуту на пользователя, проект и экран.

Каждое обращение к содержимому записи фиксируется в журнале аудита продукта, и запись в журнал делается до выдачи данных: если зафиксировать просмотр не удалось, запрос завершается ошибкой и содержимое не отдаётся. Три разных действия пишутся отдельно:

Действие в журнале Когда
replay.viewed содержимое записи выдано
replay.view.failed записи нет или её не удалось прочитать
replay.access.denied настоящий отказ по правам или по тарифу

Отсутствующая или повреждённая запись никогда не выглядит в журнале как запрет доступа — это разные события, и путать их при разборе инцидента не придётся.

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

Записи о просмотрах отнесены к обязательной категории и хранятся 7 лет (обычные записи журнала — 1 год). Журнал устроен как append-only: изменение и удаление его строк запрещены на уровне базы, и API удаления записей журнала для администратора проекта не существует.

Честный остаток: список сессий содержит сырые значения — идентификатор сессии, идентификатор человека, адрес входа и последний адрес. Он доступен той же роли «Аналитик». Отпечаток вместо идентификатора применяется в журнале аудита, а не в самом продукте.

Сколько хранятся записи и что удаляется по запросу человека

Срок хранения задаётся тарифом (от 7 дней до 90 дней). Записи старше срока удаляются ежедневной задачей очистки — именно удаляются, а не скрываются от интерфейса. Поверх тарифа действует общий предел хранилища в 90 дней: дольше части записей не живут ни при каких настройках.

Два следствия, которые стоит учесть заранее:

  • если у организации нет действующего тарифа или триала, записи не хранятся вовсе — ближайшая очистка удалит все части записей проекта;
  • если перейти на тариф без записей, произойдёт то же самое: возможность выключается, и хранение обнуляется.

Удаление данных субъекта (Настройки → Данные → Удаление данных субъекта) удаляет записи вместе с остальными данными человека: в задании есть отдельная стадия «Удаление записей сессий». Удаляются те части записей, чей идентификатор попал в граф идентичности этого проекта — сам user_id и связанные с ним анонимные идентификаторы.

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

Остаточные риски

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

Риск Что это значит Как снизить
Стандартный режим текста весь видимый текст страницы попадает в хранилище, если стандартный режим разрешён и проектом, и интеграцией не ослаблять локальный режим в интеграции; если ослабили под задачу — вернуть обратно
Персональные данные в атрибутах значения data-* сохраняются, если имя атрибута не похоже на секрет, а значение — на ссылку не держать имена, адреса и номера документов в атрибутах внутри записываемой области
Персональные данные в адресах страниц адрес входа и последний адрес видны в списке сессий; фильтр по паспорту к адресам не применяется намеренно, чтобы не портить числовые идентификаторы не выносить персональные данные в путь и параметры адреса
Маскирование зависит от разметки новый блок, добавленный при редизайне, по умолчанию записывается ревизия data-pp-block включена в чек-лист выпуска
Роль «Аналитик» — это доступ ко всем записям проекта ограничения «только свои сессии» не существует выдавать роль поимённо, остальным — «Наблюдатель»
Аудит фиксирует просмотр, но не мешает ему журнал — это разбор после, а не запрет сочетать с минимизацией ролей
Удалённое исчезает не мгновенно вытесненные части хранилища живут минуты; резервные копии — по своему сроку учитывать в сроках ответа на запрос субъекта
Согласие живёт в браузере состояние согласия не сохраняется между загрузками страницы вызывать выдачу согласия из CMP на каждой загрузке, см. согласие

Перед включением на сайте с медицинскими или платёжными данными

Порядок, который стоит пройти до того, как записи включены хотя бы для одного процента сессий.

  1. Оставьте строгий режим текста в обоих местах — и в настройке проекта, и в интеграции. Не «включим сейчас стандартный, чтобы было понятнее»: вернуть режим потом можно, а стереть уже записанное придётся удалением данных.
  2. Разметьте чувствительные области data-pp-block. Карточка пациента, форма оплаты, просмотр документов, переписка, любой блок, где появляется номер карты, диагноз или паспортные данные.
  3. Проверьте адреса страниц. Персональные данные в пути или параметрах адреса попадут в список сессий и в события.
  4. Проверьте атрибуты разметки внутри записываемых областей — они сохраняются как есть.
  5. Убедитесь, что платёжная форма отдаётся сторонним фреймом, если это так: кросс-доменные фреймы не записываются вообще, и это самая надёжная граница из доступных.
  6. Включите согласие. С data-consent="required" запись не стартует, пока согласие не выдано — ни один байт разметки не уйдёт до этого.
  7. Начните с маленькой доли записей и посмотрите первые записи сами, до того как роль «Аналитик» появится у команды.
  8. Сократите круг доступа. Пересмотрите, кому в организации действительно нужна роль «Аналитик» — см. роли и права.
  9. Опишите записи в политике конфиденциальности: что записывается, зачем, на какой срок, кто смотрит и как запросить удаление. Готового юридического текста продукт не даёт, и наличие технических мер само по себе не подтверждает соответствие 152-ФЗ, GDPR или другому закону — правовое основание и процедуры определяете вы.
  10. Проверьте процедуру удаления данных субъекта на тестовом человеке до первого реального запроса, а не после.

Если хотя бы один пункт не проходит — записи лучше не включать: собранное уже нельзя «не собирать», его можно только удалять.