В конце 2021 года мир информационной безопасности оказался потрясён одним из самых масштабных скандалов, связанных с уязвимостями программного обеспечения – историей с Log4Shell. Эта критическая уязвимость в библиотеке Log4J, используемой для логирования в Java-приложениях, дала возможность злоумышленникам осуществлять удалённое выполнение кода на системах жертв. Однако в тени громкой истории Log4Shell оставались две менее заметные, но не менее опасные уязвимости, которые раскрылись позже и продолжают представлять серьёзную угрозу. Рассмотрим подробнее их суть, механизм эксплуатации и способы защиты от них. Log4J – это одна из самых распространённых библиотек для ведения логов в Java, она присутствует во множестве корпоративных и публичных проектов, от небольших приложений до крупных облачных сервисов.
Уязвимости, обнаруженные в этой библиотеке, связаны с особенностями обработки и интерполяции строк, из-за чего в неё были внедрены опасные возможности обработки внешних данных. Первой, наиболее известной стала уязвимость Log4Shell (CVE-2021-44228), которая позволяла внедрять в логи вызовы JNDI и загружать вредоносный код с удалённых серверов. После её обнаружения и начальных патчей оказалось, что проблемы Log4J глубже и комплекснее. Две главные уязвимости, оставшиеся в тени, – отказ в обслуживании (DoS) и утечка данных. Первая из них эксплуатирует особенности рекурсивной обработки строк в Log4J.
В этой библиотеке многие виды строковых подстановок реализованы через рекурсивные вызовы. Уязвимость проявляется в том, что злоумышленник может подготовить специально сконструированный лог-сообщение с глубоко вложенными подстановками, что приводит к исчерпанию памяти стека Java и вызову ошибки StackOverflowError. Практическая опасность данной уязвимости заключается в том, что достаточно отправить вредоносный лог — и возможно остановить или перезапустить сервер без необходимости сложного взаимодействия с ним. Такой сценарий значительно осложняет обнаружение и блокировку атаки, поскольку она не требует обратной связи от цели. Важный нюанс – размер стека Java и конфигурации JVM влияют на масштаб атаки – чем меньше стек, тем проще добиться отказа в обслуживании.
Специфические тестовые эксплоиты продемонстрировали, что нагрузка для успешной атаки относительно невелика, что делает проблему реальной даже на современных системах. Вторая уязвимость связана с утечкой данных через подстановки. Log4J изначально поддерживает множество паттернов для подстановки значений, таких как переменные окружения, свойства системы, параметры Spring и Docker, а также собственные элементы контекста лога. Несмотря на то, что класс JNDILookup, связанный с процедурой Log4Shell, после первого скандала был удалён или обезврежен во многих версиях, остальные типы подстановок остаются доступными. Это означает, что в конфигурационных файлах или в записи логов можно использовать опасные конструкции вроде ${env:POSTGRES_PASSWORD} или ${spring:spring.
mail.password}, которые потенциально могут раскрыть конфиденциальные данные системы. Проблема усугубляется тем, что доступ к логам могут иметь не только администраторы, но и пользователи SaaS-приложений, что серьёзно расширяет вектор атак. Для успешного проведения такой атаки злоумышленнику необходимо иметь возможность управлять контентом, который попадает в логи, либо добраться до конфигурационных файлов Log4J, где паттерны этих подстановок могут использоваться. Логирование является важным инструментом для поддержки и мониторинга проектов, однако подстановка значений с возможностью обращаться к ресурсам извне приводит к серьёзным рискам.
Производитель Apache и команда разработки Log4J отреагировали на открытые вопросы, выпустив обновления и предприняв дополнительные меры безопасности. Тем не менее, версия 2.19 и выше, официально закрывающие уязвимости, не решают проблему полностью, если нарушен принцип безопасности доступа к конфигурационным файлам и логам. Для защиты от первой уязвимости отказа в обслуживании рекомендовано обновиться до последних версий Log4J, в которых рекурсивные подстановки либо ограничены, либо отключены по умолчанию. Настройка параметров JVM и контроль за стековой памятью также дают дополнительный уровень защиты от DoS-атак.
Перевод логирования в безопасный режим, исключение из конфигураций вызовов Context Lookup и удаление класса JndiLookup — важные меры, которые должны быть реализованы независимо от версии библиотеки. Ситуация с утечкой данных требует тщательного ревью конфигурационных файлов Log4J. Запрет на использование потенциально опасных подстановок и переход к безопасным альтернативам, а также жёсткий контроль доступа к логам – ключевые элементы защиты. В корпоративных средах необходимо использовать IDS и WAF решения с актуальными сигнатурами, отсекающими подозрительную активность и шаблоны, напоминающие лог-атаки. Несмотря на масштабность проблемы, опыт показывает, что мало кто обновляет все используемые зависимые библиотеки сразу, оставляя свои системы уязвимыми.
Кроме того, постоянный доступ к конфигам Log4J, который может сохраняться в некоторых системах, даёт злоумышленникам возможность обходить даже обновления безопасности. Важно понимать, что логирование – это инструмент, тесно связанный с архитектурой приложений, поэтому всё решение лежит не только в патчах, но и в грамотной архитектуре и политике безопасности. Привлечение специалистов по безопасной настройке, аудит конфигураций и мониторинг аномалий в логах помогут своевременно выявлять и предотвращать скрытые угрозы. История Log4shell и связанных с ней скрытых уязвимостей стала важным уроком индустрии. Она показала, как давно забытые архитектурные решения, типа поддержки JNDI, могут через взаимодействие с другими компонентами создавать огромные риски.
Также это пример того, что закрытие главной дыры не всегда означает полное устранение угрозы – остаются дополнительные уязвимости, о которых нужно знать и своевременно бороться. В конечном счёте, безопасность — процесс постоянный, требующий постоянного внимания и эксплуатации лучших практик. Обновления, ограничения и контроль доступа — основа защиты современных приложений, в том числе тех, что используют Java и Log4J. Если задержаться с обновлением, риск компрометации сервисов и утечки информации только растёт. Поэтому осознание и понимание даже менее заметных багов в Log4J, таких как отказ в обслуживании и утечка данных через подстановки, имеет критическое значение для практиков в области безопасности, сисадминов и разработчиков.
Только комплексный подход и своевременная реакция позволяют сохранить системы надёжными и устойчивыми к новым угрозам, которые появляются по следам таких гигантских инцидентов, как Log4shell.