Анализатор обнаружил логирование данных из внешнего источника без предварительной проверки. Это может нарушить процессы логирования или скомпрометировать содержание логов.
Ошибки, связанные с логированием данных, относятся к категории A09:2021 – Security Logging and Monitoring Failures списка OWASP Top 10 Application Security Risks.
Если логирование пользовательского ввода производится без проверок, то злоумышленник может внедрить произвольные данные в лог.
Рассмотрим пример. Предположим, что логи хранятся в простом текстовом формате. Узнать формат хранения логов можно разными способами. Например, если проект имеет открытый исходный код или с помощью какой-либо другой атаки. Возможный лог может иметь такой вид:
INFO: User 'SomeUser' entered value: '2022'.
INFO: User 'SomeUser' logged out.
Код, осуществляющий логирование, может выглядеть так:
public class InputHelper
{
HttpRequest Request {get; set;}
Logger logger;
string UserName;
void ProcessUserInput()
{
string userInput = Request["UserInput"];
string logMessage = "INFO: User '"
+ UserName
+ "' entered value: '"
+ userInput + "'.";
logger.Log(logMessage);
....
}
}
В таком случае злоумышленник может внедрить произвольные данные о событиях, которые никогда не происходили.
Например, злоумышленник вводит такой текст:
2022/r/nINFO: User 'Admin' logged out.
Тогда в логах появится такая запись, которая может ввести человека, анализирующего логи, в заблуждение:
INFO: User 'SomeUser' entered value: '2022'.
INFO: User 'Admin' logged out.
Рассмотрим другой вид атаки. Например, если логи хранятся в формате XML, то злоумышленник может внедрить такие данные, которые сделают содержимое отчёта некорректным. Также последующий процесс парсинга готовых логов может выдать неправильные данные или завершиться ошибкой. Пример уязвимого кода:
public class InputHelper
{
HttpRequest Request {get; set;}
Logger logger;
void ProcessUserInput()
{
string userID = Request["userID"];
logger.Info(userID); // <=
....
}
}
Злоумышленник может внедрить незакрытый тег и сделать невозможным парсинг XML-файла.
Список возможных уязвимостей зависит от архитектуры и настроек ввода, логгера, вывода логов или иных частей системы логирования. Например, атака на логи в формате XML может иметь следующие последствия:
Некоторых атак можно избежать экранированием символов, чтобы они не рассматривались как часть XML-синтаксиса. Например, начальный символ тега "<" следует экранировать как "<". Некоторые стандартные методы .NET для работы с XML, например, наследники 'XNode', реализуют экранирование записываемых в XML-дерево данных. Также .NET предоставляет отдельные от инфраструктуры XML классы для обеспечения безопасности. Пример более безопасного кода, использующего кодирование:
public class InputHelper
{
HttpRequest Request {get; set;}
Logger logger;
string EscapeCharsForXmlLog(string userInput)
{
return SecurityElement.Escape(userInput);
}
void ProcessUserInput()
{
string userInput = Request["userID"];
userInput = EscapeCharsForXmlLog(userInput);
logger.Info(userInput); // <=
....
}
}
Ещё один пример: стандарт JSON запрещает наличие null-символов ("\0") в файлах. Если злоумышленник внедрит этот символ, это может сломать процесс сохранения или просмотра готовых логов. Null-символ следует экранировать как "\u0000".
Другой пример: если логи хранятся в реляционной СУБД, использующей SQL, отсутствие проверок входных данных может привести к SQL-инъекции (подробнее: диагностика V5608).
Также анализатор считает источниками небезопасных данных параметры методов, доступных из других сборок. Более подробно эта тема раскрыта в заметке "Почему важно проверять значения параметров общедоступных методов". Рассмотрим пример:
public class InputHelper
{
Logger logger;
public void ProcessInput(string input)
{
Log("Input logged:" + input);
}
private void Log(string input)
{
logger.Log(LogLevel.Information, input);
}
}
В этом случае анализатор выдаст предупреждение низкого уровня достоверности на вызов метода 'Log'. Заражённый результат конкатенации строк используется для логирования.
Сделать этот код более безопасным можно также, как в примере выше — кодированием строки:
public class InputHelper
{
Logger logger;
public void ProcessInput(string input)
{
Log(SecurityElement.Escape("Input logged:" + input));
}
private void Log(string input)
{
logger.Log(LogLevel.Information, input);
}
}
Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки непроверенного использования чувствительных данных (ввода пользователя, файлов, сети и пр.). |
Данная диагностика классифицируется как:
|