Insufficient Logging — недостаточное ведение журнала
Ведение журнала (логирование) — ключевой элемент безопасности и стабильности системы. Оно помогает отслеживать действия пользователей, администраторов и разработчиков, а также автоматические процессы, такие как сборка, тестирование и развертывание и обновление приложений.
Недостаточное ведение журнала может затруднять ряд процессов, связанных с разработкой ПО. Например, без подробного журнала сложно определить причины ошибок в системе, провести аудит или проверку. Кроме того, в некоторых отраслях и странах есть строгие требования к ведению журналов для обеспечения безопасности данных.
Чтобы избежать этих проблем, важно разработать и внедрить эффективную систему ведения журналов, которая включает:
- Определение критических событий, которые необходимо отслеживать, например вход пользователей, изменения конфигураций, обновления кода.
- Автоматическое логирование с помощью специальных инструментов и библиотек.
- Механизмы анализа и мониторинга журналов для выявления потенциальных угроз и неполадок.
- Обучение сотрудников и разработчиков правилам ведения журнала.
Например, если в веб-приложении на Spring Boot требуется логировать запросы и ответы, достаточно добавить специальный фильтр:
@Slf4j
@Order(2)
@Component
public class RequestLoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// Запись информации о запросе
logRequest(httpRequest);
try {
// Продолжение цепочки фильтров
chain.doFilter(request, response);
} finally {
// Запись информации об ответе и времени выполнения
logResponse(httpRequest, httpResponse);
}
}
private void logRequest(HttpServletRequest request) {
String requestURI = request.getRequestURI();
String method = request.getMethod();
log.info("Запрос: {} - {}", method, requestURI);
}
private void logResponse(HttpServletRequest request, HttpServletResponse response) {
int statusCode = response.getStatus();
log.info("Ответ: HTTP {} - {}", statusCode, request.getRequestURI());
}
}
Improper Output Neutralization for Logs — неправильная нейтрализация выходных данных для журналов
Это правило подчеркивает важность грамотного управления данными, которые собираются при работе с системами или приложениями. Нейтрализация выходных данных включает удаление или маскировку чувствительной информации, такой как пароли, номера кредитных карт и личные данные. Неправильная нейтрализация может привести к утечке данных, несоответствию требованиям безопасности и конфиденциальности, установленным законодательством, а также репутационным рискам.
Пример нарушения этого правила:
@Slf4j
public class LoginService {
public void loginToLog(String username) {
// Логируем login как есть
log.info("user login: " + username);
}
}
Здесь функция loginToLog() не соответствует стандартам безопасности, поскольку включает имя пользователя в запись журнала при регистрации пользователя. Если имя пользователя содержит специальные символы, это может привести к возникновению уязвимостей и подделке данных.
Как исправить?
Для нормализации логина применим метод sanitize(). Он нормализует выходные данные путем удаления любых потенциально вредоносных и нежелательных символов в имени пользователя. Метод можно настроить с учетом конкретных требований и контекста приложения.
@Slf4j
public class LoginService {
public void loginToLog(String username) {
// Для нормализации логина применяем метод sanitize()
String sanitizedUsername = sanitize(username);
// И после этого логируем username
log.info("user login: " + sanitizedUsername);
}
private String sanitize(String input) {
// Удаляем все лишние и нежелательные символы
return input.replaceAll("[^a-zA-Z0-9]", "");
}
}
Omission of Security-relevant Information — упущение информации, касающейся безопасности
Критически важную информацию необходимо включать в процесс разработки программного обеспечения. Например, отсутствие ключевых данных о потенциальных угрозах или уязвимостях может сделать систему более уязвимой к атакам. Также неучтенная информация может привести к нарушению нормативных требований и серьезным последствиям, включая репутационные риски и штрафы.
Избежать этих проблем помогут следующие меры:
- Определение критических данных, которые являются ключевыми для обеспечения безопасности и должны быть включены в процесс разработки.
- Разработка механизма для регулярного обмена информацией о потенциальных угрозах и уязвимостях между командами.
- Обучение сотрудников и разработчиков основам безопасности и лучшим практикам в области DevSecOps.
- Регулярный аудит и проверки на соответствие нормам безопасности.
Пример нарушения правила:
@Slf4j
@Service
public class PaymentService {
public void processPayment(String creditCardNumber, double amount) {
// Тут должен быть код проводимой транзакции
// Логирование без надлежащей информации
log.info("Payment processed");
}
}
В этом коде фиксируется только сам факт вызова метода. Это не дает понимания, что происходит на самом деле, а также может усложнять поиск проблем безопасности или ошибок.
Как исправить?
Необходимо расширить лог, добавив в него информацию о данных транзакции, которые предварительно нужно обезличить.
@Slf4j
@Service
public class PaymentService {
public void processPayment(String creditCardNumber, double amount) {
// Тут должен быть код проводимой транзакции
// Логирование без надлежащей информации
Logger logger = Logger.getLogger(PaymentService.class.getName());
logger.info("Payment processed - Credit Card: " +
maskCreditCardNumber(creditCardNumber) + ", Amount: " + amount);
}
private String maskCreditCardNumber(String creditCardNumber) {
return "************" + creditCardNumber.substring(creditCardNumber.length() - 4);
}
}
Deserialization of Untrusted Data — десериализация ненадежных данных
Десериализация — это процесс преобразования бинарных данных обратно в структуры, которые можно использовать в программе. В контексте DevSecOps и безопасности десериализация ненадежных данных представляет собой потенциальную угрозу безопасности, поскольку она позволяет атакующим эксплуатировать уязвимости в приложениях.
Чтобы избежать рисков, используйте безопасные практики работы с данными:
- Проверка входящих данных на предмет вредоносного кода или неожиданных значений.
- Использование безопасных библиотек и фреймворков для работы с данными, которые обеспечивают защиту от известных уязвимостей.
- Обновление ПО, включая библиотеки и фреймворки, чтобы закрыть известные уязвимости.
- Тестирование безопасности в процессе разработки, чтобы выявлять потенциальные уязвимости на ранних этапах.
Сделаем выводы:
- Ведение журнала (логирование) — ключевой элемент безопасности и стабильности системы. Оно помогает отслеживать действия пользователей, администраторов и разработчиков, а также автоматические процессы, такие как сборка, тестирование и развертывание приложений.
- Недостаточное ведение журнала может осложнять процесс разработки ПО, в частности устранение неполадок в приложениях, соблюдение нормативных требований и проведение аудитов.
- При ведении журналов необходимо определять критические события, автоматизировать сам процесс логирования, уделять внимание механизмам анализа и мониторинга журналов, обучать разработчиков правилам логирования.
- Нейтрализация выходных данных — это удаление или маскировка чувствительной информации. Неправильная нейтрализация может привести к утечкам, нарушениям нормативных требований и репутационным рискам.
- При разработке ПО необходимо учитывать критически важную информацию. Для этого нужно не только определить, что является критическими данными, но и заниматься информированием, уделять внимание обучению сотрудников, аудитам и проверкам.
- Десериализация — это процесс преобразования бинарных данных обратно в структуры, которые можно использовать в программе. В контексте DevSecOps и безопасности десериализация ненадежных данных представляет собой потенциальную угрозу безопасности, поскольку она позволяет атакующим эксплуатировать уязвимости в приложениях.