> Что происходит с персональными данными при обработке (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Wildberries
Стек: Go
> Пример ответа
Короткий ответ
При обработке персональных данных в Go-сервисах ключевое - это жизненный цикл данных: сбор, передача, хранение и удаление. Основные риски - утечки через логи, ошибки сериализации, недостаточная защита при передаче и хранении. На практике нужно минимизировать объём собираемых данных, шифровать их в покое и в транзите, ограничивать доступ по принципу least privilege, а также обеспечить возможность удаления по запросу пользователя (right to be forgotten). Важно помнить про compliance (GDPR, 152-ФЗ) и аудит действий с данными.
Подробное объяснение
Персональные данные (ПДн) - это любая информация, относящаяся к прямо или косвенно определённому физическому лицу. В контексте backend-разработки на Go обработка ПДн включает несколько этапов:
- Сбор - получение данных от клиента (HTTP-запросы, формы, API). Здесь важно валидировать входные данные и не собирать лишнего (data minimization).
- Передача - движение данных между сервисами, в БД, в очереди. Критично использовать TLS для внешних и внутренних коммуникаций, а также не логировать чувствительные поля.
- Хранение - данные в БД, кэше, файлах. Нужно шифрование (AES-256, транзитное шифрование диска), маскирование, разделение доступа.
- Обработка - бизнес-логика, агрегация, аналитика. Здесь важно избегать попадания ПДн в метрики, логи, трейсы.
- Удаление - по запросу пользователя или по истечении срока хранения. Нужно реализовать физическое удаление, а не мягкую пометку.
В Go специфические моменты:
- Сериализация - при работе с JSON/Protobuf легко случайно включить лишние поля (например, через
json:"-"или omitempty). - Горутины и конкурентность - данные могут копироваться в несколько мест одновременно, что усложняет контроль доступа.
- Инструменты - стандартная библиотека не предоставляет встроенных механизмов шифрования на уровне типов, поэтому нужно использовать
crypto/aes,crypto/randи т.д.
Также важно разделять понятия: анонимизация (необратимое удаление связи с личностью) и псевдонимизация (замена идентификаторов на псевдонимы). Для compliance часто достаточно псевдонимизации.
На практике
На практике в Go-проектах я бы делал следующее:
- Определить PII-поля в моделях и пометить их (например, через структуру с тегами или отдельный пакет).
- Использовать middleware для логирования, который автоматически маскирует поля (email, phone, passport).
- Настроить шифрование на уровне приложения для особо чувствительных полей (например, номер карты) - хранить в БД только зашифрованные значения.
- Ограничить доступ к данным через сервисный слой, а не через прямые запросы к БД.
- Реализовать endpoint для удаления данных (DELETE /users/{id}/data) с полным каскадным удалением.
- Добавить audit log - кто, когда и зачем обращался к данным (без самих данных).
- Использовать context для передачи userID и проверки прав доступа на каждом уровне.
Важно помнить, что даже если вы используете managed-БД (PostgreSQL, Redis), шифрование на уровне приложения - это дополнительный слой защиты, особенно если БД может быть скомпрометирована.
Пример кода
GOpackage mainimport ("crypto/aes""crypto/cipher""crypto/rand""encoding/base64""errors""io")// EncryptField шифрует строку с помощью AES-GCMfunc EncryptField(plaintext string, key []byte) (string, error) {block, err := aes.NewCipher(key)if err != nil {return "", err}gcm, err := cipher.NewGCM(block)if err != nil {return "", err}nonce := make([]byte, gcm.NonceSize())if _, err := io.ReadFull(rand.Reader, nonce); err != nil {return "", err}ciphertext := gcm.Seal(nonce, nonce, []byte(plaintext), nil)return base64.StdEncoding.EncodeToString(ciphertext), nil}// DecryptField расшифровывает строкуfunc DecryptField(encoded string, key []byte) (string, error) {data, err := base64.StdEncoding.DecodeString(encoded)if err != nil {return "", err}block, err := aes.NewCipher(key)if err != nil {return "", err}gcm, err := cipher.NewGCM(block)if err != nil {return "", err}nonceSize := gcm.NonceSize()if len(data) < nonceSize {return "", errors.New("ciphertext too short")}nonce, ciphertext := data[:nonceSize], data[nonceSize:]plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)if err != nil {return "", err}return string(plaintext), nil}
Пример middleware для маскирования email в логах:
GOfunc MaskEmail(email string) string {parts := strings.Split(email, "@")if len(parts) != 2 {return "***"}name := parts[0]if len(name) <= 2 {return "***@" + parts[1]}return name[:2] + "***@" + parts[1]}
Как отвечать на собеседовании
Начни с определения ПДн и их жизненного цикла. Затем переходи к конкретике: какие риски существуют в Go-приложениях (логи, сериализация, конкурентность). Обязательно упомяни compliance (GDPR, 152-ФЗ) - это показывает понимание бизнес-контекста. Приведи пример из практики: как ты решал проблему утечки данных через логи или как реализовывал шифрование. Если спросят про удаление - расскажи про каскадное удаление и физическое стирание. Не углубляйся в криптографию, если не спрашивают, но покажи, что знаешь про AES-GCM и почему не стоит использовать ECB.
Что проверяет интервьюер
Интервьюер оценивает:
- понимание жизненного цикла данных и точек риска;
- знание практических инструментов (шифрование, маскирование, audit log);
- умение применять принципы data minimization и least privilege;
- осведомлённость о регуляторных требованиях;
- способность проектировать безопасные API и хранилища.
Также проверяется, насколько ты системно мыслишь: не просто "шифруем всё", а понимаешь trade-off между производительностью и безопасностью, умеешь выбирать, что шифровать, а что нет.
Типичные ошибки
- Шифровать всё подряд - это убивает производительность и усложняет поиск по данным. Нужно шифровать только чувствительные поля.
- Логировать ПДн - самая частая ошибка. Даже в debug-логах не должно быть email, телефонов, адресов.
- Игнорировать удаление - мягкая пометка
deleted_atне является удалением с точки зрения GDPR. - Хранить ключи в коде - ключи шифрования должны быть в секрет-менеджере (Vault, AWS KMS), а не в env-переменных в репозитории.
- Не проверять права доступа - если любой пользователь может запросить данные другого через API, шифрование не спасёт.
- Использовать слабые алгоритмы - например, MD5 для хеширования паролей или AES-ECB для шифрования.
> Похожие задачи по Go
Есть ли у TCP и UDP операция подтверждения доставки
Что происходит если памяти не хватает
Какие данные кэшируются и как работает кэширование
Как подбирать тайм-ауты для backend взаимодействия, например HTTP запросов
> Похожие задачи по backend
Есть ли у TCP и UDP операция подтверждения доставки
Что происходит если памяти не хватает
Какие данные кэшируются и как работает кэширование
Как подбирать тайм-ауты для backend взаимодействия, например HTTP запросов
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью