Разработка с персональными данными: тестовые данные, логи и доступы

0
9
Обложка статьи: Разработка с персональными данными: тестовые данные, логи и доступы

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

Статья опирается на логику направления «Безопасность данных» из методики зрелости Группы Сбер (источник); это методика для крупных компаний, мы используем её как ориентир и пересказываем своими словами. Принципы обработки данных: объём соответствует целям, хранение не дольше необходимого (статья 5 152-ФЗ, в редакции базы «Гарант»); конкретные требования для вашей системы согласуйте с ответственным за ПДн.

Что должно получиться

Уровень Что это значит на практике
1. Базовый Известно, где хранятся важные и персональные данные; резервные копии существуют
2. Гигиенический Данные классифицированы; копии 3-2-1 с проверенным восстановлением; секреты не лежат в репозиториях; передача наружу защищена; тестовые среды без реальных данных

Критерии сформулированы нами по мотивам методики, это ориентир, а не оценка соответствия.

Принцип: боевые данные остаются в боевой среде

Среда Какие данные допустимы Кто имеет доступ
Разработка (ноутбук) Только синтетические или полностью обезличенные Разработчик
Тест и приёмка Синтетические или обезличенные; реальные только по решению ответственного, с теми же мерами защиты, что у боевой среды Команда тестирования
Боевая среда Реальные данные Ограниченный круг по заявке, с журналированием

Если реальные данные в тестовой среде неизбежны (отладка редкой ошибки), оформите это как исключение: ограниченный срок, перечень лиц, защита как у боевой среды, уничтожение после использования: уничтожение ПДн.

Тестовые данные

  • Синтетические данные. Генерируйте вымышленные записи, повторяющие форму реальных: имена, адреса, номера в нужных форматах. Для Python удобны библиотеки генерации тестовых данных (например, Faker); для общих проверок используйте документационные адреса и домены: example.com, 192.0.2.0/24.
  • Обезличенная копия боевой базы. Если нужна реалистичная структура и распределение, делайте выгрузку с заменой идентификаторов и обобщением: обезличивание ПДн. Процесс выгрузки автоматизируйте, чтобы сырой дамп не появлялся на машинах разработчиков.
  • Нет «временных» дампов. Контролируйте, куда выгружаются копии баз и кто может скачать; для разработчиков отключите прямой доступ к боевым резервным копиям: резервное копирование.
  • Тестовые адреса. Тестовая среда не должна отправлять письма и SMS реальным людям: используйте перехватчики почты и заглушки.

Журналы приложений

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

  • Не писать ПДн в журнал. Фиксируйте идентификаторы записей и события, а не содержимое: «обновлён клиент 12345», а не ФИО и телефон.
  • Маскировать на выходе. Добавьте фильтр, который заменяет почту, телефоны и номера карт в сообщениях, как страховку от случайных утечек.
  • Ограничить доступ и срок хранения. Журналы с возможными ПДн хранятся ограниченное время и читаются узким кругом: журналы ИСПДн.
  • Не логировать запросы целиком. Тела запросов с формами, заголовки с токенами и пароли исключайте из журналов шлюзов и прокси.
  • Проверять сторонние сервисы сбора ошибок и мониторинга: они получают содержимое сообщений: облачные сервисы и ПДн.

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

#!/usr/bin/env python3
"""Фильтр для стандартного logging: маскирует почту, телефон и похожие на номер карты последовательности в сообщениях.
Подключите к обработчику: handler.addFilter(MaskPII()). Это защитная сетка, а не замена правилу «не писать ПДн в журнал»."""
import logging
import re

PATTERNS = [
    (re.compile(r'[\w.+-]+@[\w-]+\.[\w.-]+'), '[email]'),
    (re.compile(r'(?<!\d)(?:\+7|8)[\s(-]*\d{3}[\s)-]*\d{3}[\s-]*\d{2}[\s-]*\d{2}(?!\d)'), '[phone]'),
    (re.compile(r'(?<!\d)(?:\d[ -]?){13,19}(?!\d)'), '[number]'),
]


def mask(text):
    for rx, repl in PATTERNS:
        text = rx.sub(repl, text)
    return text


class MaskPII(logging.Filter):
    def filter(self, record):
        record.msg = mask(record.getMessage())
        record.args = ()
        return True


if __name__ == '__main__':
    handler = logging.StreamHandler()
    handler.addFilter(MaskPII())
    log = logging.getLogger('demo')
    log.addHandler(handler)
    log.setLevel(logging.INFO)
    log.info('Заказ от ivan@example.com, тел. +7 900 123-45-67, карта 4111 1111 1111 1111, сумма %s', 1500)

Результат запуска демонстрации в конце файла (python3 mask_logs.py):

Заказ от [email], тел. [phone], карта [number], сумма 1500

Подключение в приложении: handler.addFilter(MaskPII()) к каждому обработчику, который пишет в файл или во внешнюю систему.

Доступы разработчиков

  • Разработчики не имеют постоянного доступа к боевым данным; при необходимости доступ выдаётся временно, по заявке и журналируется: управление доступом.
  • Отдельные учётные записи для администрирования боевой среды; MFA на входе.
  • Разделение обязанностей: тот, кто разрабатывает изменение, не выкатывает его в боевую среду единолично: управление изменениями.
  • Подрядчики-разработчики подчиняются тем же правилам и договору поручения, если получают доступ к данным: поручение обработки.

Секреты и конфигурация

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

Проверки в конвейере

Проверка Что ловит
Поиск секретов Ключи и пароли в коде и истории
Сканирование зависимостей и образов Известные уязвимости: Dependency-Track и SonarQube в GitLab CI
Статический анализ Небезопасная работа с данными, SQL-инъекции
Проверка на ПДн в тестовых данных Файлы с реальными адресами, телефонами, документами: скрипт поиска ПДн
Проверка конфигураций Режим отладки, открытые административные интерфейсы, подробные сообщения об ошибках

Контейнеры и инфраструктура

Запускайте контейнеры без лишних прав и не храните данные в образах: Docker: запуск не от root. Тома с данными шифруйте и ограничивайте доступ, а в тестовые окружения не подключайте боевые тома.

Диагностика

Симптом Причина и что делать
В тестовой базе реальные клиенты Копия боевой базы без обезличивания. Замените автоматической обезличенной выгрузкой, удалите старые копии, проверьте, куда они попали
В журналах номера телефонов и карт Приложение логирует тела запросов. Исключите поля, добавьте фильтр маскирования, сократите срок хранения
Разработчик хранит дамп боевой базы на ноутбуке Нет запрета и контроля. Шифруйте диски, отзовите доступ к дампам, обучите: шифрование дисков
Секрет попал в репозиторий Отзовите и замените секрет, очистите историю, добавьте проверку в конвейер

Где это в модели зрелости

Материал относится к направлению «Безопасность данных» (материалы направления, карта зрелости). Уровень 2 требует классификации данных, защищённой передачи, отсутствия секретов в репозиториях и тестовых сред без реальных персональных данных: эта статья описывает, как этого добиться в разработке.

Как проверить

  1. В тестовых и разработческих средах нет реальных персональных данных, проверка выполнена скриптом поиска.
  2. Журналы приложений не содержат ФИО, телефонов, почты и номеров карт; фильтр маскирования подключён.
  3. У разработчиков нет постоянного доступа к боевым данным; доступ выдаётся по заявке и журналируется.
  4. В конвейере работают проверки секретов и зависимостей; секреты не лежат в репозитории.

Источники

  • Методика оценки уровня зрелости кибербезопасности компании, Группа Сбер: sberbank.ru.
  • Федеральный закон от 27.07.2006 № 152-ФЗ «О персональных данных», статья 5: КонсультантПлюс. Проверяйте действующую редакцию.
  • OWASP Logging Cheat Sheet: owasp.org. Международная практика, не российский норматив.

Оставьте свой ответ