> Что происходит с персональными данными при обработке (Go)

Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы

Компании: Wildberries

Стек: Go

> Пример ответа

Короткий ответ

При обработке персональных данных в Go-сервисах ключевое - это жизненный цикл данных: сбор, передача, хранение и удаление. Основные риски - утечки через логи, ошибки сериализации, недостаточная защита при передаче и хранении. На практике нужно минимизировать объём собираемых данных, шифровать их в покое и в транзите, ограничивать доступ по принципу least privilege, а также обеспечить возможность удаления по запросу пользователя (right to be forgotten). Важно помнить про compliance (GDPR, 152-ФЗ) и аудит действий с данными.

Подробное объяснение

Персональные данные (ПДн) - это любая информация, относящаяся к прямо или косвенно определённому физическому лицу. В контексте backend-разработки на Go обработка ПДн включает несколько этапов:

  1. Сбор - получение данных от клиента (HTTP-запросы, формы, API). Здесь важно валидировать входные данные и не собирать лишнего (data minimization).
  2. Передача - движение данных между сервисами, в БД, в очереди. Критично использовать TLS для внешних и внутренних коммуникаций, а также не логировать чувствительные поля.
  3. Хранение - данные в БД, кэше, файлах. Нужно шифрование (AES-256, транзитное шифрование диска), маскирование, разделение доступа.
  4. Обработка - бизнес-логика, агрегация, аналитика. Здесь важно избегать попадания ПДн в метрики, логи, трейсы.
  5. Удаление - по запросу пользователя или по истечении срока хранения. Нужно реализовать физическое удаление, а не мягкую пометку.

В 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), шифрование на уровне приложения - это дополнительный слой защиты, особенно если БД может быть скомпрометирована.

Пример кода

GO
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"errors"
"io"
)
// EncryptField шифрует строку с помощью AES-GCM
func 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 в логах:

GO
func 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 для шифрования.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью