middle
Что и как логировать с точки зрения безопасности?
Security-логирование — фиксация событий безопасности (аутентификация, авторизация, критичные операции) в структурированном формате для обнаружения инцидентов, аудита и соответствия требованиям регуляторов.
Что НЕОБХОДИМО логировать
- События аутентификации:
Пример
log.info("Успешная аутентификация: user={}, ip={}, userAgent={}",
username, request.getRemoteAddr(), request.getHeader("User-Agent"));
log.warn("Неудачная попытка аутентификации: user={}, ip={}, причина={}",
username, request.getRemoteAddr(), failureReason);
- Действия авторизации:
Пример
log.info("Доступ разрешён: user={}, action={}, resource={}",
username, "VIEW_ACCOUNT", accountId);
log.warn("Доступ запрещён: user={}, action={}, resource={}, причина={}",
username, "TRANSFER", accountId, "insufficient_role");
- Критичные бизнес-операции:
Пример
log.info("Создание перевода: user={}, from={}, to={}, amount={}, traceId={}",
username, fromAccount, toAccount, amount, traceId);
- Системные события безопасности:
Пример
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"
// }
Хранение и защита логов
- Centralized logging — отправлять логи в централизованную систему (ELK, Splunk, Graylog)
- Неизменяемость — логи должны быть защищены от модификации (append-only)
- Ретенция — хранить логи аудита не менее 1-3 лет (требование регуляторов)
- Контроль доступа — доступ к логам ограничен
- Шифрование — при хранении и при передаче
На собеседовании: интервьюер ожидает два списка: что логировать (аутентификация, авторизация, бизнес-операции) и что категорически нельзя (пароли, карты, токены). Частая ошибка — не упомянуть маскирование данных и структурированные логи для SIEM.