Обезл***вание д***ных — это не просто рандомизация



    В банке есть проблема: нужно давать доступ к базе данных разработчикам и тестировщикам. Есть куча клиентских данных, которые по PCI DSS требованиям Центробанка и законам о персональных данных вообще нельзя использовать для раскрытия на отделы разработки и тестирования.

    Казалось бы, достаточно просто поменять всё на какие-нибудь несимметричные хеши, и всё будет хорошо.

    Так вот, не будет.

    Дело в том, что база данных банка — это множество связанных между собой таблиц. Где-то они связаны по ФИО и номеру счёта клиента. Где-то по его уникальному идентификатору. Где-то (тут начинается боль) через хранимую процедуру, которая вычисляет сквозной идентификатор на основе этой и соседней таблицы. И так далее.

    Обычная ситуация, что разработчик первой версии системы уже десять лет как умер или уехал, а системы ядра, запущенные в старом гипервизоре внутри нового гипервизора (чтобы обеспечить совместимость) ещё в проде.

    То есть прежде чем всё это обезличить, сначала надо разобраться в базе данных.



    Кто делает обезличивание и зачем?


    Обезличиванием или маскированием занимаются потому, что есть законы и стандарты. Да, гораздо лучше тестировать на «снапшоте прода», но за такой залёт регуляторы могут и отозвать лицензию. То есть прикрыть бизнес как таковой.

    Любое обезличивание — это достаточно дорогая и неповоротливая прослойка между продуктивными системами и тестированием с разработкой.

    Цель проектов по обезличиванию (маскированию) практически всегда — подготовить данные для тестирования, максимально похожие на реальные, хранящиеся в продуктивных базах. То есть если данные содержат ошибки — вместо email забит телефон, вместо кириллицы в фамилии латиница и т. п., то и замаскированные данные должны быть такого же качества, но изменёнными до неузнаваемости. Вторая цель — уменьшение объёма баз данных, которые используются в тестировании и разработке. Полный объём оставляют только под нагрузочное тестирование, а под остальные задачи обычно делается некий срез данных по заранее определённым правилам — усечение БД. Третья цель — получить связанные между собой данные в разных замаскированных и усечённых базах. Имеется в виду, что данные в разных системах, в разное время, должны быть обезличены единообразно.

    По вычислительной сложности обезличивание — это примерно как несколько архивирований базы данных на предельной компрессии. Алгоритм примерно похож. Разница в том, что алгоритмы архивирования оттачивались годами и дошли до почти максимального КПД. А алгоритмы обезличивания пишут так, чтобы они хотя бы работали на текущей базе и были достаточно универсальными. И софт после обезличивания вообще заработал. То есть отличный результат — перемолоть 40 ТБ за ночь. Бывает так, что заказчику дешевле загонять в обезличивание базу раз в полгода на неделю на слабеньком сервере — тоже подход.



    Как заменяются данные?


    Каждый тип данных меняется в соответствии с правилами, которые могут использоваться в коде. Например, если мы заменим ФИО на случайный хеш со спецсимволами и цифрами, то первая же проверка корректности данных сразу выдаст ошибку в реальном тестировании.

    Поэтому сначала система обезличивания должна определить, что за тип данных хранится в поле. В зависимости от вендора используются разные подходы от ручной разметки до попыток дискаверинга базы и автоопределения, что же там хранится. У нас есть практика внедрения всех основных решений на рынке. Разберём один из вариантов, когда есть визард, который пытается найти данные и «угадать», что там за тип данных хранится.



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

    Итак, предположим, после всего этого мы видим таблицу, в которой есть поле «ФИО». Визард уже за нас его разметил как ФИО, и нам остаётся только подтвердить и выбрать тип обезличивания. Визард предлагает случайную замену на славянские имена (есть базы для разных регионов). Мы соглашаемся и получаем замены вроде Иван Иванов Петренко — Иосиф Альбертович Чингачгук. Если это важно, сохраняется пол, если нет — замены идут по всей базе имён.

    Примеры замен:
    Джеймс К. Максвелл -> Альберт Эйнштейн
    Макс Планк -> Чарльз Дарвин
    Галилео Галилей -> Майкл Фарадей
    Исаак Ньютон -> Никола Тесла
    Мария Кюри -> Барбара Мак-Клинток
    Следующее поле — дата в юникстайме. Визард это тоже определил, а нам надо выбрать функцию обезличивания. Обычно даты используются для контроля последовательности событий, и ситуации, когда клиент сначала сделал перевод в банке, а потом открыл счёт, никому особо не нужны на тестировании. Поэтому мы задаём небольшую дельту — по умолчанию в пределах 30 дней. Ошибки всё равно будут, но если это критично, можно настроить более сложные правила, дописав свой скрипт в обработку обезличивания.

    Адрес должен валидироваться, поэтому используется база российских адресов. Номер карточки должен соответствовать реальным номерам и валидироваться по ним. Иногда бывает задача «сделать все Визы случайными Мастеркардами» — это тоже выполнимо в пару кликов.
    Под капотом визарда находится профилирование. Профилирование — это поиск данных в БД по заранее заданным правилам (атрибутам, доменам). Фактически мы читаем каждую ячейку базы данных заказчика, применяем к каждой ячейке набор регулярных выражений, сравниваем значения в этой ячейке со словарями и т. д. В результате чего имеем набор сработавших правил на столбцах таблиц базы данных. Профилирование мы можем настраивать, можем читать не все таблицы в БД, можем брать только определённое количество строк из таблицы или определённый процент строк.



    Что происходит внутри?


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

    Если есть размеченные соответствия «имя кириллицей — имя латиницей», то они должны быть явно обозначены на этапе разработки, и тогда в таблице замен они будут соответствовать друг другу. То есть имя кириллицей будет обезличено, а потом эта обезличенная запись будет сконвертирована в латиницу, например. В этом моменте мы отходим от подхода «не улучшать качество данных в системе», но это один из компромиссов на которые приходится идти ради какой-никакой, но производительности системы. Практика показывает, что если нагрузочное, функциональное тестирование в своей работе не замечает компромисса, то ничего не было. И тут всплывает важный момент, что обезличивание в целом это не шифрование. Если у вас пару ярдов записей в таблице, а в десятке из них ИНН не изменился, то что? То ничего, этот десяток записей не найти.

    После окончания процесса таблицы перекодировки остаются в защищённой базе сервера обезличивания. База нарезается (усекается) и передается в тестирование без таблиц перекодировки, таким образом, для тестировщика обезличивание становится необратимым.

    Полная обезличенная база передаётся тестировщикам для нагрузочного тестирования.

    Это значит, что во время работы с БД таблица перекодировки «пухнет» (точный объём зависит от выбора замен и их типа), но рабочая база остаётся исходного размера.

    Как примерно выглядит процесс в интерфейсе оператора?


    Общий вид IDE на примере одного из вендоров:



    Дебаггер:



    Запуск трансформации из IDE:



    Настройка выражения для поиска чувствительных данных в профилировщике:



    Страница с набором правил для профилировщика:



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



    Все ли данные в базе маскируются?


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

    Логика в том, что если мы замаскировали ФИО пациента в больнице, можно маскировать или не маскировать диагноз — всё равно никто не узнает, от кого он. У нас был случай, когда примечания к операции в банке просто маскировали случайными буквами. Там были заметки уровня: «В кредите отказано, так как клиент пришёл пьяным, его вырвало на стойку». С точки зрения отладки это просто строка символов. Ну вот пусть ей и остаётся.

    Пример стратегий:



    Динамическая seed-таблица это таблица перекодировки в которую складываем уже случившиеся перекодировки. Хеш может быть сильно разный и в случае того же ИНН, чаще генерируется новый случайный ИНН с сохранением первых символов, с контрольными цифрами.

    Можно ли менять данные средствами самой СУБД?


    Да. При обезличивании данных есть два основных подхода — изменять данные в БД средствами самой БД либо организовать ETL-процесс и менять данные посредством стороннего софта.

    Ключевой плюс первого подхода — данные не надо никуда из базы выносить, нет затрат на сеть, используются быстрые и оптимизированные средства БД. Ключевой минус — отдельная разработка под каждую систему, отсутствие общих таблиц перекодировки для разных систем. Таблицы перекодировки нужны для воспроизводимости обезличивания, дальнейшей интеграции данных между системами.

    Ключевой плюс второго подхода — неважно, какая у вас БД, система, файл это или какой-то веб-интерфейс, — один раз реализовав какое-то правило, вы можете использовать его везде. Ключевой минус — надо читать данные из базы, обрабатывать их отдельным приложением, записывать в базу обратно.

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



    То есть сделать можем всё, что угодно, но в банковском секторе очень хорошо зарекомендовал себя именно ETL-подход.

    А почему данные просто не портят вручную?


    Один раз так можно сделать. Кто-то просидит три дня, обезличит кучу данных и подготовит базу данных на 500-1000 записей. Сложность в том, что процесс надо повторять регулярно (с каждым изменением структуры БД и появлением новых полей и таблиц) и на больших объёмах (для разных видов тестирования). Обычный запрос — обезличить первые 10-50 ГБ базы так, чтобы этот объём пришёлся на каждую таблицу равномерно.

    Что делать, если в базе хранятся сканы документов?


    Если документ можно свести к XML и конвертировать обратно (это, например, документы офиса), — можно провести и обезличивание в них. Но иногда бывают бинарники вроде сканов паспортов в PDF/JPG/TIFF/BMP. В этом случае общепринятая практика — нагенерить сторонним скриптом похожих документов и подменять реальные на образцы из базы нагенерённых случайным образом. Сложнее всего с фотографиями, но есть сервисы вроде этого, которые примерно похожим образом решают вопрос.

    Кто за что отвечает?




    При обновлении после изменения ПО или «вдогонку» процессы попроще.

    А что, если на тестах что-то пойдёт не так?


    Обычно так и случается. Во-первых, тестировщики после первого прогона обезличивания точнее формулируют требования к базе. Мы можем поменять правила обезличивания или отбраковывать записи вроде «вот тут действия должны идти в хронологическом порядке, а не в хаотичном». Во-вторых, в зависимости от внедрения мы или поддерживаем обезличивание по мере изменения базы, либо оставляем всю документацию, описания структуры БД и типов обработки, передаём весь код обработки (правила в xml/sql) и обучаем специалистов у заказчика.

    Как посмотреть демо?


    Самый простой способ — написать мне на почту PSemenov@technoserv.com.
    Техносерв
    Компания

    Комментарии 24

      +1
      Интересно, а зачем маскировать дату рождения? Ведь она не только не уникальна, но даже не «почти уникальна» (как ФИО, например — в России каждый день рождается почти по 5000 человек, а при Союзе было еще больше). Имея только дату рождения, вряд ли можно сделать какие-то выводы о клиенте, если остальные данные преобразованы до неузнаваемости (разве что о возрасте, но ведь в статье говорится о сдвиге даты с сохранением возраста). Собственно,
      Логика в том, что если мы замаскировали ФИО пациента в больнице, можно маскировать или не маскировать диагноз — всё равно никто не узнает, от кого он.


      Почему такая логика неприменима к дате рождения?
        +1
        Потому что дата рождения — часть базовых предопределённых наборов, составляющих персональные данные. Она в сочетании с другими данными с высокой вероятностью даёт ПД. Да, по логике она редко сама по себе деперсонализирует. Вот наш старый пост про то, как работают ПД.
          +4

          Все-таки дата рождения это самый надёжный случайный хэш для человека. Особенно для относительно небольших выборок в несколько сотен человек. Когда звоню в больницу, школу и тд для быстрого поиска они спрашивают дату рождения пациента студента (пол они знают их контекста) — второго вопроса почти никогда не следует, сразу называют правильную фамилию.


          Можно подумать что у банка клиентов десятки тысяч, но, мне кажется, в тестовой БД все равно останутся неизменные параметры — например, год открытия счета, пол, город — которые разобьют всю выборку на группы в несколько десятков /сотен человек. Дата рождения в такой группе почти наверняка деанонимизирует

            0

            В статье написано, что адрес-таки меняется целиком, включая регион и город.

          +7
          Спасибо, интересная статья. Но вот по этому поводу
          Логика в том, что если мы замаскировали ФИО пациента в больнице, можно маскировать или не маскировать диагноз — всё равно никто не узнает, от кого он.

          сразу вспомнился (возможно несколько теоретический) пример из обсуждения GDPR: если в деревне на сто человек, только один страдает от такого заболевания — то не замаскировав его диагноз — вы автоматом раскрываете его и все остальные не маскированные данные связанные с этим персонажем.
            0
            Да, но там же не 100 человек, а 50 гиг данных и адреса уже изменены, так что никто не узнает, был ли там кто из той деревни
              0
              тут кстати другой интересный вопрос: когда говорят о гигабайтах данных — немалая часть из них, ИМХО, это информация о транзакциях и прочая служебные и / или «не персональные» данные, а вот на ФИО, приходится существенно меньшая часть этих гигабайт. И перебор может выдавать уже очень интересные результаты. Там как раз в следующем комментарии от автора — есть ссылка на их же статью про ПД с интересными примерами. ;)
              0
              Вот тут мы подробнее писали про то, что считать персональными данными. И про случай с диагнозом там тоже есть.
              +1

              Интересно, если ли opensource решения для обезличивания данных базы PostgreSQL.
              Цель обезличивание и копирование продовой базы в тест/препрод/UAT для тестирования.

              0
              менять коля на вася? потом легко обратно поменять
              мы делали кол на имя1, вася на имя2, где 1 и 2 — коды записи

              ну и надо разрабов в штат банка взять и не парить с обезличкой
                0
                Разрабы в банке с доступом к живым данным клиентов нарушают принцип наименьших привилегий.
                  0
                  Генерировать новые имена в стиле имя1 один из самых популярных способов. Думаю, что каждый разработчик, который сталкивался с задачей деперсонализации своей БД начинал решать её именно таким образом.

                  Но, если коротко, такие имена портят селективность, меняют размер индексов, затрудняют работу функциональных тестировщиков, а самое главное коренным образом меняют структуру данных, убирая возможные ошибки в них. Самый простой пример — в реальной БД могут содержаться имена содержащие смешанные буквы латиницы и кириллицы. Фамилия «Семенов» может быть с латинской буквы C, а может быть с русской буквы С.

                  Разработчики в штате не должны иметь доступ к финансовым данным клиентов.
                  –1
                  Обезличивание и рандомизация?
                  прочитав заголовок сразу появляется мысль, что автор просто не понимает ни первого ни второго.
                  однако по тексту — уже такой явной ошибки вроде нет…
                  но вчитавшись все же остается впечатление поверхностного изложения
                    0
                    А что вы за продукт описываете? Мы недавно смотрели Redgate Data Masker(для SQL Server), но там конечно не дешевые цены www.red-gate.com/products/dba/data-masker
                      0
                      Скриншоты из Ataccama One, но статья не преследует цели описать какой-то продукт. Больше про наш подход, который может быть реализован и на платформах других вендоров и про маскирование в целом.
                      0
                      В нашем банке как то тоже была проблема с обезличиванием перс данных клиентов.Но проблема кроется не с самим процессом обезличиванием информации а выборке записей(т.е. конкретных клиентов, их платежи, взаимосвязи с другими клиентами и прочее).Т.е. согласно закону должны быть обезличены данные по клиентам по которым прошел срок обработки информации(5 лет).
                      А разработчики банковского ПО данный факт не предусмотрели.Хотя бы должна быть дата последнего обслуживания в банке.
                      Для тестовой схемы для предоставления сторонним разработчикам согласен что нужно маскировать все перс данные и по всем клиентам нужно.
                        0
                        А как-то решается задача обеспечения полноты обезличивания? Когда работал в банке сталкивался, что основные очевидные таблицы были обезличены, но в дальних неочевидных уголках (типа складского учета оригиналов договоров) можно было все еще найти данные о клиентах.
                          0
                          Задача решается «профилированием БД». С помощью специальных инструментов и правил читается как вся БД, так и только некая часть данных. Например, 10% от количества строк в таблице, но не менее 200 000. После чего к каждой прочитанной ячейке применяются правила (регулярки) которые говорят «да» или «нет». Например, у нас есть регулярка, которая проверяет, что число является ИНН. Смотрит на размер 10 или 12 чисел, смотрит на то, что на конце контрольные числа и говорит true на каждое успешное вхождение.

                          Прочитав и обработав таким образом БД мы получаем некий отчет, который потом желательно проверить глазами.

                          Обычно разработка указывает на 20-30 таблиц с персональными данными, а после профилирования таких таблиц 100-300.
                            0
                            Спасибо, то есть проблема не уникальна
                          0
                          Интересная статья, спасибо.
                          Пару вопросов, нет ли случаев, и как с ними бороться:
                          1. Есть хэш / цифровая подпись, и при изменении любого атрибута (имени, даты) — всё портится. А если подпись приватным ключом клиента?
                          2. С датами, сдвиг без изменения возраста не возможен в принципе. Возможен только без изменения «количества лет» на определённую дату. Поменяли дату на 25 дней раньше, а оказалось что кто-то получил документ ещё не родившись, или сделал что-то раньше чем ему разрешено это по закону. (например снял деньги со вклада до наступления 18 лет).
                          3. Есть ли обработка геоданных (GPS Координаты)?
                            0
                            1. Любой хэш придётся пересчитывать. Бывают даже ID составные натуральные+синтетика. То есть приходится для новых данных генерировать хэши в полном объеме и никуда от этого не деться. В случае цифровой подписи, на мой взгляд, достаточно нескольких тестовых клиентов и их ключа. Например, читаем/пишем таблицу в четыре потока — вот пусть и будет четыре подписи. С точки зрения качества данных под тестирование, вроде, не должно быть проблем.

                            2. На практике пока не сталкивались с подобными проблемами. Но они конечно же возможны.

                            3. Геоданные — это два набора цифр. Их можно перемешать или можно менять последние три символа числа, или делать с ними ещё что-то подобное. Вопрос, чего вы хотите добиться. Чисто теоретически можно даже генерировать реальный адрес, потом у того же Яндекса запрашивать координаты и подставлять настоящие. Работать это дело будет, безусловно, очень медленно.
                              0

                              Работал в финтехе до 2018. Не скажу где, смысл в том, что бэк-офис с покером и программистами был в России, а фронт с продажами и директором в Москве. То есть нагрянуть в бэк ВНЕЗАПНО — эта вероятность была близка к нулю. А у фронтов не было доступа никуда, даже у директора.


                              Намаявшись с 1 и 2 пришли к тому, что все прогеры работали с дампами реальной базы. Единственное что было захэшировано — номер паспорта, но заклинание для расшифровки тоже каждый знал.


                              Вроде как нехорошо и все такое, но из-за 1 и 2 работать было ну просто невозможно, вы часть причин описали.

                              0
                              FFaker::Random.seed=user.id
                              user.name = FFaker::Name.name
                              user.email = FFaker::Internet.email
                              


                              Profit!

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое