Персональные данные на сайте - где лежат, выгрузка, удаление
Разбираемся, где сайт хранит данные людей, как собрать выгрузку по конкретному человеку и что можно удалить по его обращению, а что придётся сохранить.
Что нужно знать заранее
Данные одного человека лежат сразу в нескольких местах сайта. Учётная запись, свойства его заказов, результаты заполненных форм, подписки и служебные журналы - это разные таблицы с разной логикой хранения.
Удалять можно не всё. Документы, которые магазин обязан хранить по закону, остаются, и в них тоже есть имя и адрес доставки, поэтому такие записи обезличивают, а не стирают.
Состав ответа на обращение человека - вопрос к юристу проекта, а не к разработчику. Разработчик отвечает за то, чтобы нужные данные можно было собрать и показать быстро и полно.
Шаги
- Составить карту мест, где сайт хранит данные людей, и держать её в описании проекта.
- Написать скрипт сбора всех данных по одному человеку с указанием источника.
- Разделить данные на удаляемые и на те, что обязаны остаться в документах.
- Обезличивать оставшееся вместо удаления и записывать факт обработки обращения.
- Согласовать сроки хранения и настроить регулярную чистку по этим срокам.
Решение
Собираем данные учётной записи:
$user = \Bitrix\Main\UserTable::getRow(['filter' => ['=ID' => $userId], 'select' => ['ID', 'LOGIN', 'NAME', 'LAST_NAME', 'EMAIL', 'PERSONAL_PHONE', 'DATE_REGISTER', 'LAST_LOGIN']]);$export = ['учётная запись' => $user];// сюда же добавляют свои поля учётной записи, если они заведены на проектеСобираем заказы и их свойства:
$orders = \Bitrix\Sale\Internals\OrderTable::getList(['filter' => ['=USER_ID' => $userId], 'select' => ['ID', 'ACCOUNT_NUMBER', 'DATE_INSERT', 'PRICE', 'STATUS_ID']])->fetchAll();foreach ($orders as &$order) { $order['СВОЙСТВА'] = \Bitrix\Sale\Internals\OrderPropsValueTable::getList([ 'filter' => ['=ORDER_ID' => $order['ID']], 'select' => ['CODE', 'NAME', 'VALUE']])->fetchAll();}$export['заказы'] = $orders;В свойствах заказа лежит адрес доставки и телефон получателя. Это самая заметная часть персональных данных магазина, и про неё чаще всего забывают при подготовке выгрузки.
Ищем упоминания в заявках и подписках:
SELECT 'форма' AS источник, ID, DATE_CREATE FROM b_form_result WHERE USER_ID = 42UNION ALLSELECT 'подписка', ID, DATE_INSERT FROM b_subscription WHERE USER_ID = 42;-- список источников зависит от того, какие модули используются на проектеОтдаём выгрузку файлом:
file_put_contents('/local/private/export-' . $userId . '.json', json_encode($export, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));// файл кладут вне публичного каталога и отдают человеку по защищённой ссылкеВыгрузку никогда не оставляют в открытом каталоге. Файл с данными человека, доступный по прямой ссылке, превращает ответ на обращение в новую утечку.
Записываем факт обработки обращения:
\Bitrix\Main\Diag\Debug::writeToFile([ 'обращение' => $requestId, 'пользователь' => $userId, 'действие' => 'выгрузка и обезличивание', 'кто' => $GLOBALS['USER']->GetID(),], date('d.m.Y H:i'), 'pdn.log');// журнал обращений хранят дольше, чем сами удалённые данныеТипичные проблемы
В выгрузке нет части данных о человеке.
Скрипт собирает только учётную запись, а данные лежат ещё в заказах, заявках и подписках. Карту мест хранения составляют заранее и обновляют при каждом новом модуле.
После удаления записи пропали документы по заказам.
Удалялась учётная запись вместе со связанными данными, которые магазин обязан хранить. Такие записи обезличивают, оставляя номера и суммы документов на месте.
Файл выгрузки нашли в открытом каталоге сайта.
Выгрузка сохранена в каталог загрузок, доступный по прямой ссылке. Файлы с данными людей хранят вне публичного каталога и отдают кодом с проверкой прав.
Подтвердить обработку обращения нечем.
Действия выполнялись вручную и нигде не записывались. Каждое обращение и каждое действие по нему фиксируют в отдельном журнале.
Данные удалены на сайте, но остались в учётной системе.
Обращение обработано только на одной стороне интеграции. Порядок обработки согласуют для обеих систем сразу и выполняют его целиком.
Частые вопросы
Где именно сайт хранит данные людей?
В учётных записях, свойствах заказов, результатах форм, подписках и служебных журналах. Точный список зависит от набора модулей и своих таблиц проекта.
Можно ли удалить всё по обращению?
Нет: документы, которые магазин обязан хранить, остаются, но их обезличивают. Состав удаляемого согласуют с юристом проекта, а не решают в коде.
Как отдать выгрузку человеку?
Файлом по ссылке с ограниченным сроком жизни и проверкой прав. Публичный каталог для таких файлов не подходит категорически.
Что делать с резервными копиями?
Указывать срок их хранения в порядке обработки обращений и не восстанавливать удалённые данные из старых копий. Отдельно чистить копии обычно не требуется.
Нужно ли трогать интеграции?
Да, если данные человека уехали в учётную систему или в сервис рассылок. Обращение обрабатывают во всех системах, куда эти данные попали.
Смежное
- Импорт пользователей - оглавление подтемы
- Чистка учётных записей: неактивные, дубли, обезличивание - как обезличивают записи с заказами
- Выгрузка пользователей: отбор, поля, персональные данные - выгрузка по группе, а не по человеку
- Согласие на обработку данных: соглашение, компонент, запись факта - основание для хранения
- Шифрование данных в базе: ключ, поле, миграция - защита чувствительных полей
- Отдача файла с проверкой прав: закрытые каталоги, заголовки, ссылки - как отдать выгрузку безопасно
- Свойства заказа: чтение, запись и фильтрация по значению - где лежат адреса и телефоны
- Пользователи, группы и права доступа - устройство учётных записей целиком