
Обнаруживайте и исправляйте уязвимый Apache Commons Text в Java-артефактах JAR/WAR; идентифицируйте классы и сканируйте байт-код на наличие точек вызова CVE-2022-42889 (Text4Shell).
Нажмите, чтобы найти:
CVE-2022-42889 может представлять серьёзную угрозу для широкого круга Java-приложений. Важные вопросы, которые разработчик может задать в этом контексте:
commons-text? Какие версии?Включает ли выпущенный код commons-text? Какая версия библиотеки в него включена? Ответить на эти вопросы может быть непросто по двум причинам:
Транзитивные зависимости: хотя commons-text может отсутствовать в списке прямых зависимостей проекта, он может использоваться косвенно через какую-либо другую зависимость.
Код этой библиотеки может не присутствовать напрямую в виде отдельного файла, а быть встроен в какой-либо другой jar-файл с кодом.
JFrog выпускает инструмент, помогающий решить эту проблему: scan_commons_text_versions. Инструмент ищет код класса StringLookupFactory (независимо от имён содержащих .jar-файлов и содержимого pom.xml) и пытается идентифицировать версии объектов, чтобы сообщить, уязвима ли включённая версия commons-text.
commons-text?Этот вопрос актуален в тех случаях, когда разработчик хочет проверить, могут ли вызовы commons-text в кодовой базе передавать потенциально контролируемые атакующим данные. Хотя самый безопасный способ устранения уязвимости, как обсуждается в рекомендациях, — применить соответствующие исправления, оценка и проверка потенциального воздействия в предположении, что commons-text не пропатчен, может быть полезна во многих ситуациях.
scan_commons_text_calls_jar.py находит вызовы уязвимых функций в скомпилированных .jar-файлах и сообщает о результатах в виде имени класса и имени метода, в которых встречается каждый вызов.
commons-text в системе; как быстро отключить опасное поведение?Обновление остаётся лучшим решением — это решение предназначено для быстрого оперативного исправления.
В контексте уязвимости CVE-2022-42889 класс org/apache/commons/text/lookup/ScriptStringLookup в commons-text позволяет выполнять скрипты, которые могут быть встроены в строку, полученную из контролируемого атакующим источника, через ${script}. Следовательно, вызовы функции ScriptStringLookup.lookup указывают на то, что эта функциональность активирована.
Мы предоставляем инструмент Text4ShellPatch, позволяющий пропатчить этот конкретный вызов, чтобы функциональность выполнения скриптов не могла быть использована. После применения патча библиотека всегда будет выполнять скрипт, возвращающий предупреждающее сообщение (вместо потенциально контролируемого атакующим кода).
Аналогично, DNS- и URL-поиск могут загружать недоверенное содержимое, если контролируются атакующим через ${dns} и ${url}; таким образом, соответствующие функции поиска DnsStringLookup и UrlStringLookup могут быть отключены патчем, чтобы возвращать предупреждающее сообщение.
Патч может быть применён к конкретному jar-файлу: только для поиска script или для script, dns и url — для лучшей защиты, если они не предназначены для использования в приложении.
Резервная копия создаётся в том же месте, где находится исходный jar-файл, перед его заменой пропатченным. Имя резервной копии соответствует следующему шаблону: <original_jar_name>_YYYY.MM.DD_HH.mm.ss.orig.jar, где YYYY, MM, DD — соответственно год, месяц и день, а HH, mm, ss — соответственно часы, минуты и секунды.
Также можно найти уязвимые версии commons-text и автоматически пропатчить их, как описано в ответе на следующий вопрос.
commons-text?Два наших инструмента вместе предоставляют возможность сканировать и исправлять уязвимые jar-файлы commons-text.
Пример bash-скрипта находится в этом репозитории GitHub под именем scan_and_patch.sh. По сути, он использует скрипт scan_commons_text_versions.py, чтобы найти в указанной root-folder уязвимые jar-файлы commons-text с уязвимой версией, и запускает против них инструмент Text4ShellPatch, как показано ниже.

scan_commons_text_versions.pypython scan_commons_text_versions.py root-folder [-quiet] [-exclude folder1 folder2 ..]
Инструмент рекурсивно сканирует root_folder на предмет .jar- и .war-файлов; в каждом найденном файле инструмент ищет StringLookupFactory.class (рекурсивно в каждом .jar-файле). Если найден хотя бы один такой класс, инструмент пытается определить его версию (включая некоторые варианты, встречающиеся в патчах и бэкпорт-патчах), чтобы сообщить, уязвим ли код.
С флагом -quiet выводятся только заключения о версиях, а остальные сообщения (файлы не найдены / не удалось открыть архивы / архивы, защищённые паролем) подавляются.
Папки, указанные после -exclude (необязательно), пропускаются.
scan_commons_text_calls_jar.pyИнструмент требует Python 3 и следующие сторонние библиотеки: jawa, tqdm, easyargs, colorama.
pip install -r requirements.txt
Вариант использования по умолчанию:
python scan_commons_text_calls_jar.py root-folder
рекурсивно сканирует все .jar-файлы в root-folder, выводя для каждого местоположения (имя класса и имя метода) вызовов методов lookup/replace/replaceIn классов StringSubstitutor/StringLookup.
Инструмент может быть настроен для дополнительных сценариев использования с помощью следующих флагов командной строки.
| Флаг | Значение по умолчанию | Назначение |
|---|---|---|
--class_regex | (.*StringSubstitutor|.*StringLookup) | Регулярное выражение для требуемого имени класса |
--method_regex | (lookup|replace|replaceIn) | Регулярное выражение для требуемого имени метода |
--quickmatch_string | (StringLookup|StringSubstitutor) | Предварительное условие для анализа файлов: .jar-файлы, не содержащие указанное регулярное выражение, будут проигнорированы |
--class_existence | Не задано | Если не задано, искать вызовы class::method, как указано регулярными выражениями. Если задано, --method_regex игнорируется, и инструмент будет искать наличие классов, заданных --class_regex, в jar-файле. |
--no_quickmatch | Не задано | Если задано, значение --quickmatch_string игнорируется и анализируются все jar-файлы |
--caller_block | .*org/apache/commons/text | Если класс-вызывающий совпадает с этим регулярным выражением, он не будет отображаться |
text_4_shell_patchjava -jar Text4ShellPatch.jar TARGET_JAR [PATCHING_MODE]
Where TARGET_JAR is the application to patch and PATCHING_MODE is
0 (default): Patch Script lookup
1: Patch Script + DNS + URL lookups
[Note: The original Jar will be kept in the same folder with the .orig.jar extension]