GDPR/CCPA. Как обрабатывать конфиденциальные данные в облачных приложениях
Всем привет! Меня зовут Сергей Синенок, и я сотрудничаю с компанией Dev.Pro в качестве Head of Delivery Practices. Я придумываю и нахожу типовые решения для разных задач, как инженер, и работаю над тем, чтобы эти решения соответствовали best practices и современным подходам к разработке. Я в индустрии разработки 15 лет, работаю преимущественно с enterprise. В последние годы фокусируюсь на engineering leadership, помогая строить и развивать команды, а также специализируюсь на cloud-native решениях.
Хоть тема безопасности в cloud-native applications и узкоспециализированная, я постарался сделать ее интересной. Какую пользу в ней можете найти вы?
- Утечки данных — это дорого. Они могут исчисляться миллионами долларов и потерянной репутацией.
- GDPR/CCPA compliance требования все чаще встречаются в современных приложениях, потому что правительство в мире начинает сильнее регулировать эту отрасль. По моему мнению, в скором будущем эта фича станет такой же распространенной, как и sign-in feature.
Что такое персональные данные (PII)
Персональные данные — это набор данных, который позволяет идентифицировать цифровой след реального человека в сети. PII могут включать в себя дату и место рождения, номер паспорта, банковской карты, водительских прав и другие данные. Все зависит от контекста и стандарта, которому мы хотим соответствовать.
GDPR и CCPA: основные моменты
GDPR (General Data Protection Regulation) — это общий регламент по защите данных в ЕС. Он декларирует несколько постулатов, которые позволяют системам и решениям быть compliant, и объясняет, как нам стоит вести себя с данными, которые мы собираем. Их принципы включают в себя:
- Законность, справедливость и прозрачность. Важно, чтобы данные были собраны легально.
- Ограничение целью. Данные должны быть собраны и обработаны так, как заявлено в политике.
- Минимизация данных. Собираем только то, что нужно. Чем больше мы знаем о пользователях, тем более высоки риски и тем серьезнее будут последствия утечек.
- Ограничение хранения данных. Не стоит хранить данные дольше нужного.
- Целостность и конфиденциальность/безопасность — не теряем :)
CCPA (California Consumer Privacy Act) — это законодательная инициатива в США касательно PII. Они декларируют, на что пользователь имеет право, раскрывая свои данные.
- Право знать — «Что на меня есть? Кому раскрываете/продаете?»
- Право на отказ — «Не продавайте мои данные никому!»
- Право доступа — «Покажите, что на меня есть».
- Право на забвение — «Удалите все обо мне!»
- Право реализации прав — компании обязаны выполнить пункты выше.
PII: основные каналы утечек
Теперь предлагаю обсудить, как эти данные можно потерять. Есть три основных канала утечки, первые два — самые распространенные:
- Утечки при передаче информации (Leak in Transit) — утечки данных при передаче между компонентами системы (HTTP, queues, Pub/Sub events, etc.).
- Утечки при хранении (Leak at Rest) — утечки файлов баз данных, томов диска, несанкционированный доступ к хранилищу.
- Утечки из памяти приложения (Leaks from the App’s Memory) — утечки дампов памяти приложения, содержащих PII данные.
Важно заметить, что атаки на enterprise происходят регулярно, поскольку на этом можно хорошо заработать. На одном из моих проектов была ситуация, когда злоумышленнику удалось получить доступ к дискам, где хранятся данные. Они зашифровали диски и просили $500 000 за ключ для расшифровки.
Также злоумышленники могут добиться несанкционированного использования системы: скачать данные и кому-то перепродать. Потенциальный ущерб таких атак сложно оценить. Если в системе не предусмотрен надлежащий мониторинг, то в какой-то момент мы можем не знать, что наши данные утекли, пока они не появятся в непредназначенном месте.
Поэтому обсудим три базовых канала, которые стоит держать на радаре, чтобы обеспечить безопасность данных в разных ситуациях.
Безопасность данных при передаче
1. Всегда использовать безопасные каналы передачи данных — HTTPS TLS v1.2 (минимум). По умолчанию в большинстве систем включена деградация протокола. Если клиент собирается подключиться по SSL 3.0, например, то система по умолчанию разрешает такую деградацию протокола — ее нужно запрещать и помнить об этом.
2. Шифрование сообщений с PII данными в очередях и топика. Если мы говорим об очередях, топиках, стримах, то вынуждены шифровать там данные для того, чтобы минимизировать риск утечки.
3. Визуализация (диаграммы) цепочек передачи данных, постоянный аудит. Уменьшить риски мы можем с помощью визуализации цепочек передач. Чтобы минимизировать риск при передаче, мы должны понимать, как данные передаются, по каким каналам их могут записать или считать.
Безопасность данных в памяти
1. Максимальная изоляция приложения от внешнего мира: Private VPC, контейнеры, принцип минимальной привилегии пользователя. Принцип минимальной привилегии гласит, что мы должны персонифицировать доступ. Плохо, когда у нас есть несколько десятков сервисов со своими хранилищами и все сервисы используют для доступа базы данных одного и того же пользователя. Теряя этого пользователя, вся база данных находится под угрозой.
2. Ручное управление памятью и контроль доступа к областям памяти с шифрованием (финансовый или медицинский домен). Поскольку этот метод сложно реализуем в современных платформах с автоматическим управлением памяти, его стоит использовать, когда есть реальная угроза. Его реализация требует осознанного подхода.
Безопасность данных при хранении:
- Role Based Access Control (RBAC) на уровне полей данных. В нужном нам хранилище базы данных можно настроить доступ к определенным полям записи определенных пользователей для определенных приложений. Мы уходим от того, чтобы пользователю, который подключается к базе данных, были доступны все данные из записей, а даем доступ только на определенные поля.
- App-level шифрование записей в БД. Можно шифровать том с данными и таким образом предотвращать опасность при краже диска. Но если злоумышленник получает доступ к базам данных через консоль, то он все еще может их считать. И с этим помогает явное шифрование приложения — тогда оно на уровне бизнес-логики знает, как зашифровать свои данные и как их потом расшифровать.
- Хеширование данных для поиска. Мы зашифровали данные, но теперь использовать поиск не так просто. В таких случаях стоит пользоваться хешированием.
- Маскировка данных в логах и метриках. В логах применяют другой подход к информации: мы ее не шифруем, а маскируем. Если, например, SSN хранится в логах (по чудному стечению обстоятельств), то мы SSN1234 превращаем в SSN000, то есть маскируем данные с именем, превращая их в подобие этих данных.
Мы рассмотрели все стандартные подходы, которые позволяют обеспечить высокий уровень безопасности данных при хранении. Стоит помнить, что их имплементация влияет на производительность системы, усложняя ее и повышая затраты на поддержку. Поэтому важно искать баланс между защитой и производительностью.
Cryptography for the rest of us
Чтобы мы могли двигаться дальше, предлагаю провести краткий экскурс в криптографию для инженеров, которые не работают каждый день с криптографией и примитивами. Мы пройдемся по верхам криптографии, чтобы понимать базовые концепции.
Что такое шифрование данных
Шифрование — обратимое преобразование информации в целях сокрытия от неавторизованных лиц, с предоставлением доступа к ней авторизованным пользователям. Главная задача шифрования — это соблюдение конфиденциальности передаваемой информации.
Важной особенностью любого алгоритма шифрования является использование ключа. По аналогии с отмычкой, дверной замок не откроется без ключа. Поэтому нам нужно понимать, что такое криптографический ключ и уметь с ним взаимодействовать.
Криптографический ключ — это секретная информация, используемая криптографическим алгоритмом при шифровании сообщений, постановке и проверке цифровой подписи, вычислении кодов аутентичности (MAC). При использовании одного и того же алгоритма результат шифрования зависит от ключа.
Для современных алгоритмов сильной криптографии утрата ключа приводит к практической невозможности расшифровать информацию.
В мире есть два подхода к шифрованию с ключом:
- Шифрование с помощью мастер-ключа — более простой и понятный подход. Мастер-ключ передаётся по различным каналам коммуникации в системе. Хоть этот способ и простой, у него есть риск: поскольку мы все шифруем одним ключом, то, если он куда-то утечет, вся наша информация будет под угрозой.
- Схема с наследованием ключей — сложнее и надежнее. Мастер-ключ не покидает заданные пределы системы, снижая риски быть скомпрометированным. Пример: схема Key Encryption Key (KEK) + Data Encryption Key (DEK).
Разберем подробнее пример шифрования KEK > DEK.
По схеме видно, что KEK порождает DEK. Из базы данных мы достаем информацию, извлекаем оттуда Data encryption key. Поскольку он зашифрован, мы его расшифровываем мастер-ключом, получаем DEK, и им же потом расшифровываем информацию. Преимущество в том, что мастер-ключ всегда лежит в безопасном месте и для шифрования данных используется множество DE ключей, которые порождены этим мастер-ключом. Если вдруг мы потеряем ключ, то подвергаем опасности только subset информацию, которая в самой системе зашифрована.
Стоит отметить, что имплементация такой системы требует более фундаментального подхода, что предполагает дополнительную стоимость.
Еще один важный концепт, который стоит упомянуть, когда мы говорим о ключах шифрования — ротация ключей шифрования.
Ротация ключей — это замена ключей шифрования в течение жизненного цикла системы. Благодаря ротации ключей мы можем:
- уменьшить ущерб от потенциальной атаки при утечке ключа;
- настроить регулярную автоматическую ротацию по расписанию;
- настроить ручную ротацию по требованию, если ключ скомпрометирован.
Поиск по зашифрованным данным
Когда данные зашифрованы, то значительно теряется функциональность поисковой системы, поскольку привычные данные заменяются символами, которые мы не можем понять. Радует то, что необязательно терять такую удобную фичу, как поиск, и можно реализовать один из нижеперечисленных подходов:
Decrypt, search, encrypt. Для этого делаем копию данных, расшифровываем, ищем, дропаем копию. Этот подход прост в реализации, но рискован, поскольку копию почти всегда легко потерять при передаче.
Decrypt, run query, send results. Это app-level поиск. Качаем данные в память, расшифровываем, ищем, получаем результат. Вариант неплохой, но плохо масштабируется, когда данных много.
Хеширование + шифрование для поиска. Кладем хеш рядом с шифрованными данными для поиска. Только точный (exact) поиск.
Проблемы с солью и консистентностью данных, хоть сам подход удобный.
Searchable Encryption Scheme. Наиболее популярный метод на сегодняшний день. Мы шифруем данные таким образом, что в encryption примитивах сохраняется некий паттерн, по которому можно понять, что это имя и это имя Джон. Такой подход сложно реализовать, и он имеет ограничения по гибкости запросов.
Шифрование бывает симметричным и асимметричным. Для сегодняшнего контекста стоит помнить, что симметричное шифрование — это шифрование одним ключом, ассиметричное — шифрование с двумя, где есть публичные и приватные ключи.
Case: шифрование данных в AWS
Теперь предлагаю перейти к кейсу, который был внедрен на одном из моих проектов. Он будет о приложении, которое связано с сетями быстрого питания. В нем хранится множество информации о клиентах, которые их заведения посещают: карты лояльности, информация о работниках сетей. В целом, ценный для злоумышленника набор персональных данных.
Кратко о системе. У нас есть два API, один из которых нужен для мобильных заказов. Есть API, который позволяет конфигурировать эти сторы удаленно через клауд. Из этих API данные собираются в data pipeline, сохраняются в MongoDB и в разные базы данных. Дальше оттуда строится репортинг, с помощью которого данные извлекаются, потом их агрегируют в AWS Redshift. И из него репорт показывается тулой Power BI.
Какие требования были к системе:
- Требовалось реализовать шифрование данных в MongoDB и Redshift, чтобы данные лежали в зашифрованном виде.
- Реализовать шифрование на уровне приложения, чтобы оно само шифровало данные и знало, как их расшифровать для дополнительной безопасности.
- Зашифровать данные при передаче.
- Симметричное шифрование AES-256-GCM.
- Ротация ключей по расписанию и по требованию.
- KEK + DEK ключи.
- Exact и Like поиск в зашифрованных данных.
- Маскировка данных в логах системы.
Что было сделано. Был проведен ресерч о том, что доступно «из коробки». Поскольку система живет в AWS-клауде, то многое оттуда было доступно. Как мы знаем, лучший код — тот, который мы не писали :)
Оттуда мы уже взяли много информации:
- HTTPS по умолчанию.
- TLS v1.2 для всей HTTPs коммуникации.
- Шифрование томов с данными для MongoDB и Redshift.
После этого мы начали думать, что делать дальше. Первое, что пришло в голову — делать самому. Я сделал прототип, но быстро понял, что со всеми требованиями система будет довольно сложная, поэтому мы с командой начали искать другое решение.
Во многом нам помогли встроенные фичи AWS — там есть key management service, который занимается созданием/ротацией ключей и всем, что требуется нашей системе. К счастью, симметричное шифрование, которое нам нужно было по требованиям, оно тоже поддерживало.
Кроме того, нам подошел AWS Encryption SDK, который умеет шифровать данные, ходить в клауд за новыми ключами, поддерживать ротацию и многое другое.
По сути, получая PII реквест, мы идем в Secret Manager, берем оттуда ключ DEK, отправляем реквест в SDK зашифровать, получаем зашифрованный payload. После мы берем зашифрованную информацию и сохраняем в базу данных.
Благодаря AWS мы получили:
- App’s field level encryption.
- Симметричное шифрование AES-256-GCM.
- Ротацию ключей по расписанию и по требованию.
- KEK + DEK ключи.
- Гораздо меньше кода.
Когда мы начали изучать нашу систему дальше, то выяснили, что связка для репортинга, где есть Redshift и Power BI, происходит через стандартный ODBC Driver и нашего кода между ними нет. Это значит, что Power BI показывает данные из Redshift в зашифрованном виде и репорты были нечитаемы.
Поэтому мы разрезали эту связь через драйвер и внедрили компонент, который сначала расшифровывает данные в Redshift и потом только Power BI их читает.
Конечно, это привело к усложнению системы. И в этом случае, это та цена за безопасность, которую мы вынуждены были заплатить. Это привело к замедлению репортов и мы начали искать практики, которые помогут нам их ускорить. В итоге замедление репортов удалось сократить до х2 и меньше, что мы расценили как хороший результат.
Полезные ссылки вместо заключения
Напоследок не могу вас оставить без полезных ссылок, которые помогут еще глубже ознакомиться с темой безопасности. Нам, инженерам, всегда нужно о ней помнить. Если у нас возникает ощущение полной безопасности, то, скорее всего, мы находимся в иллюзии и данные в это время уже куда-то утекают :)
4 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів