Gymterview
middle

Что и как логировать с точки зрения безопасности?

Security-логирование — фиксация событий безопасности (аутентификация, авторизация, критичные операции) в структурированном формате для обнаружения инцидентов, аудита и соответствия требованиям регуляторов.

Что НЕОБХОДИМО логировать

  1. События аутентификации:
Пример
log.info("Успешная аутентификация: user={}, ip={}, userAgent={}",
    username, request.getRemoteAddr(), request.getHeader("User-Agent"));

log.warn("Неудачная попытка аутентификации: user={}, ip={}, причина={}",
    username, request.getRemoteAddr(), failureReason);
  1. Действия авторизации:
Пример
log.info("Доступ разрешён: user={}, action={}, resource={}",
    username, "VIEW_ACCOUNT", accountId);

log.warn("Доступ запрещён: user={}, action={}, resource={}, причина={}",
    username, "TRANSFER", accountId, "insufficient_role");
  1. Критичные бизнес-операции:
Пример
log.info("Создание перевода: user={}, from={}, to={}, amount={}, traceId={}",
    username, fromAccount, toAccount, amount, traceId);
  1. Системные события безопасности:
Пример
log.warn("Подозрительная активность: user={}, ip={}, причина=множественные запросы",
    username, ip);

Что НЕЛЬЗЯ логировать

Пример
// ЗАПРЕЩЕНО: пароли
log.info("Логин: user={}, password={}", user, password);

// ЗАПРЕЩЕНО: полные номера карт
log.info("Оплата картой: {}", cardNumber);

// ЗАПРЕЩЕНО: токены доступа, CVV/CVC, PIN-коды, приватные ключи

Маскирование данных в логах

Пример
public class MaskingUtil {
    public static String maskCardNumber(String pan) {
        if (pan == null || pan.length() < 10) return "****";
        return pan.substring(0, 6) + "****" + pan.substring(pan.length() - 4);
        // 411111****1111
    }

    public static String maskEmail(String email) {
        return email.replaceAll("(^[^@]{2})[^@]*(@.*)", "$1****$2");
        // iv****@mail.ru
    }
}

log.info("Оплата картой: {}", MaskingUtil.maskCardNumber(cardNumber));

Logback: автоматическое маскирование

Пример
<!-- logback-spring.xml -->
<configuration>
    <conversionRule conversionWord="mask"
        converterClass="com.mybank.logging.MaskingConverter" />

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>%d{ISO8601} [%thread] %-5level %logger - %mask(%msg)%n</pattern>
        </encoder>
    </appender>
</configuration>

Структурированное логирование (JSON)

Пример использования MDC
// Использование MDC для контекста
MDC.put("userId", username);
MDC.put("traceId", traceId);
MDC.put("ip", request.getRemoteAddr());

log.info("Перевод выполнен: transferId={}, amount={}", transferId, amount);

// В JSON-формате:
// {
//   "timestamp": "2024-01-15T10:30:00Z",
//   "level": "INFO",
//   "userId": "ivanov",
//   "traceId": "abc-123",
//   "ip": "10.0.1.50",
//   "message": "Перевод выполнен: transferId=T-001, amount=50000"
// }

Хранение и защита логов

  1. Centralized logging — отправлять логи в централизованную систему (ELK, Splunk, Graylog)
  2. Неизменяемость — логи должны быть защищены от модификации (append-only)
  3. Ретенция — хранить логи аудита не менее 1-3 лет (требование регуляторов)
  4. Контроль доступа — доступ к логам ограничен
  5. Шифрование — при хранении и при передаче

На собеседовании: интервьюер ожидает два списка: что логировать (аутентификация, авторизация, бизнес-операции) и что категорически нельзя (пароли, карты, токены). Частая ошибка — не упомянуть маскирование данных и структурированные логи для SIEM.