Приватность записей сессий
Что попадает в запись сессии и что не попадает никогда, как исключить блок разметки и замаскировать текст, кто может смотреть записи, что фиксирует аудит и что удаляется при удалении данных человека.
На этой странице
Запись сессии — единственная часть 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 —
добавляются в запись с пустым содержимым. В тело записи не переносятся ни
селектор, ни адрес страницы, ни текст ошибки: в запись попадает только факт, что
в этот момент произошло событие с таким именем.
Поля ввода и текст страницы
Разделите два независимых механизма — их часто путают.
Поля ввода. Маскирование всех полей ввода включено всегда и не отключается ничем: ни настройкой проекта, ни тарифом, ни параметром вызова. Пароли маскируются отдельным безусловным правилом. То есть даже в самом «открытом» режиме то, что человек печатает, в записи не видно.
Остальной текст страницы. Здесь работают два независимых переключателя, и применяется более строгий из них:
- настройка проекта Настройки → Сбор и приватность → Записи сессий → «Текст на странице»;
- режим, заданный самой интеграцией в браузере.
| Режим | Что в записи | По умолчанию |
|---|---|---|
| Строгий — маскировать весь текст | текста страницы нет вообще: видна структура и поведение | да |
| Стандартный — маскировать ввод и пароли | текст виден; поля ввода по-прежнему замаскированы | нет |
Строгий режим — значение по умолчанию для проекта, у которого настройки ни разу не менялись, и он же применяется, если трекер не смог получить конфигурацию сбора.
Отдельного атрибута для маскирования фрагмента — вида 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 на каждой загрузке, см. согласие |
Перед включением на сайте с медицинскими или платёжными данными
Порядок, который стоит пройти до того, как записи включены хотя бы для одного процента сессий.
- Оставьте строгий режим текста в обоих местах — и в настройке проекта, и в интеграции. Не «включим сейчас стандартный, чтобы было понятнее»: вернуть режим потом можно, а стереть уже записанное придётся удалением данных.
- Разметьте чувствительные области
data-pp-block. Карточка пациента, форма оплаты, просмотр документов, переписка, любой блок, где появляется номер карты, диагноз или паспортные данные. - Проверьте адреса страниц. Персональные данные в пути или параметрах адреса попадут в список сессий и в события.
- Проверьте атрибуты разметки внутри записываемых областей — они сохраняются как есть.
- Убедитесь, что платёжная форма отдаётся сторонним фреймом, если это так: кросс-доменные фреймы не записываются вообще, и это самая надёжная граница из доступных.
- Включите согласие. С
data-consent="required"запись не стартует, пока согласие не выдано — ни один байт разметки не уйдёт до этого. - Начните с маленькой доли записей и посмотрите первые записи сами, до того как роль «Аналитик» появится у команды.
- Сократите круг доступа. Пересмотрите, кому в организации действительно нужна роль «Аналитик» — см. роли и права.
- Опишите записи в политике конфиденциальности: что записывается, зачем, на какой срок, кто смотрит и как запросить удаление. Готового юридического текста продукт не даёт, и наличие технических мер само по себе не подтверждает соответствие 152-ФЗ, GDPR или другому закону — правовое основание и процедуры определяете вы.
- Проверьте процедуру удаления данных субъекта на тестовом человеке до первого реального запроса, а не после.
Если хотя бы один пункт не проходит — записи лучше не включать: собранное уже нельзя «не собирать», его можно только удалять.