
обходное решение общего назначения для уязвимости log4j CVE-2021-44228
Этот проект предоставляет обходное решение общего назначения для уязвимости log4j CVE-2021-44228, которое можно использовать в случае, если у вас нет альтернативы в краткосрочной перспективе для пересборки вашего проекта или исправления jar-файлов log4j-core.
Идея довольно проста: мы заставляем загрузчик классов загрузить «пустую» версию класса JndiLookup с помощью опции Java runtime «-Xbootclasspath/a».
Следовательно, всё обходное решение состоит только из этого одного класса «org.apache.logging.log4j.core.lookup.JndiLookup.java» и не имеет других зависимостей.
Также для удобства прилагается pom.xml, чтобы скомпилировать и упаковать его в jar с помощью Maven, но вы также можете сделать то же самое, просто используя предпочитаемую JDK с командами «javac» и «jar».
Обратите внимание, что эта пустая версия класса «JndiLookup» не может быть совместима с оригинальной реализацией log4j2, поскольку это приведёт к сбою в определённых ситуациях загрузки классов.
При применении обходного решения вы увидите следующее сообщение:
"WARN JNDI lookup class is not available because this JRE does not support JNDI.
JNDI string lookups will not be available, continuing configuration.
Ignoring java.lang.ClassCastException: class org.apache.logging.log4j.core.lookup.JndiLookup"
Тем не менее, Log4j2 будет продолжать работать без проблем, просто без использования JNDI lookup — и готово — JNDI lookup отключён!
После компиляции класса и создания jar-файла просто добавьте опцию «-Xbootclasspath/a:<путь к вашему файлу обходного решения>» в начало вашей Java-команды и укажите каталог, в котором находится jar-файл (например, log4j-workaround-1.0-SNAPSHOT.jar). Смотрите раздел доказательства концепции для примера.
Java-команда, к которой вы примените это обходное решение, может запускать что угодно (Weblgic, Tomcat, толстый jar, собранный spring, ...).
Вы можете пропустить следующее, если вас интересует только обходное решение, а не проверка того, действительно ли оно работает.
Для проверки подхода я добавил папку «POC», в которой находится ещё один проект Maven. Я не хотел использовать модульное тестирование, а скорее оставаться ближе к производственным средам, которые используют явный запуск fat jar из командной строки или запуск контейнера, как Tomcat, с которым я проверял.
Доказательство концепции содержит два класса: «POC.java» для проверки обходного решения в командной строке и «POCServlet.java» для той же проверки в сервере приложений.
Оба сценария пытаются записать в лог «${jndi:ldap://localhost/test}», из-за чего log4j попытается подключиться к LDAP на вашем локальном хосте без применения обходного решения и завершится ошибкой «Connection refused»..
Для запуска POC из командной строки (после сборки в Maven):
Перейдите в каталог «target\log4j-workaround-1.0-SNAPSHOT\WEB-INF» и выполните (если вы используете командную строку Windows):
java -Xbootclasspath/a:..\..\..\..\target\log4j-workaround-1.0-SNAPSHOT.jar -classpath classes;lib\* com.github.grimch.log4j_workaround.poc.POC
Для запуска POC в Tomcat:
Зачем вообще использовать «-Xbootclasspath», а не просто поместить jar обходного решения первым в «обычный» classpath? Ну, некоторые контейнеры позволяют влиять на загрузку классов таким образом, что jar-файлы в развернутом архиве приложения имеют приоритет над теми же файлами в системном classpath. С другой стороны, то, что находится в bootstrap classpath, имеет приоритет над всем остальным.
Однако, если вы уверены, что не используете ничего подобного (например, «prefer-application-packages» в Weblogic"), то вы также можете использовать альтернативу «-classpath».