Анализ уязвимостей обработки XML в Apache NiFi за последние 3 года

Apache NiFi XML уязвимости дата-инженерия безопасность администрирование примеры курсы обучение, Apache NiFi курсы примеры обучение, курсы дата-инженеров, обучение инженеров данных, обучение большим данным, Школа Больших Данных Учебный Центр Коммерсант

Мы уже упоминали, что в Apache NiFi 1.20 устранена уязвимость CVE-2023-22832, связанная с неправильным ограничением ссылок на внешние объекты XML в процессоре ExtractCCDAAttributes. Сегодня более подробно поговорим про проблемы обработки XML-документов в Apache NiFi и способы их решения.

Чем опасны внешние сущности в XML

Обработка внешних сущностей XML считается довольно проблемной функцией языка разметки из-за уязвимости приложения перед набором угроз. В зависимости от среды развертывания обработка внешних сущностей XML уязвима для атак типа «отказ в обслуживании» (Denial-of-Service attack), раскрытия конфиденциальной информации и перечисления сетевых ресурсов.

Определение типа XML-документа (DTD, Document Type Definition) является наиболее распространенным местом для внешних ссылок. Различные синтаксические XML-анализаторы интерпретируют объявления сущностей и запрашивают при этом ссылочные ресурсы. Например, следующий XML-документ содержит DTD, который объявляет внешний объект с именем конфигурации, на который документ ссылается в исходном элементе:

<?xml version="1.0" ?>
<!DOCTYPE source [
  <!ENTITY configuration SYSTEM "http://localhost/configuration">
]>
<source>&configuration;</source>

Во время парсинга синтаксический XML-анализатор делает запрос к URL-адресу http://localhost/configuration и заменяет сущность &configuration возвращенным ответом. Это может пригодиться при обработке информации из надежных источников, но делает приложение уязвимым. Хотя встроенные абстракции фреймворка могут обеспечить защиту от этих проблем, использование возможностей XML во многих языках программирования требует тщательной реализации, чтобы избежать опасного кода.

В частности, API Java, на котором написан Apache NiFi, для обработки XML включает несколько классов конфигурации и программных интерфейсов, выполняющих различные операции. Для этого в спецификации JAXP (Java API for XML Processing), включающей набор абстрактных API, упрощающих обработку XML данных с помощью Java-программ, существует несколько категорий:

  • Объектная модель документа (DOM, Document Object Model);
  • Преобразования расширяемого языка таблицы стилей (XSLT, Extensible Stylesheet Language Transformations), о котором мы писали здесь;
  • Простой API для XML (SAX, Simple API for XML);
  • Потоковый API для XML (StAX, Streaming API for XML).

JAXP также поддерживает возможности валидации схемы и XML Path Language. Каждая категория требует тщательной оценки и настройки для реализации безопасной системы.

Apache NiFi обрабатывает XML различными способами, используя компоненты своей инфраструктуры и расширения. Формат XML обеспечивает настройку компонентов аутентификации и авторизации, а также обеспечивает передачу структурированных данных для настраиваемых потоков данных.

В течение прошлого, 2022 года вышло несколько релизов Apache NiFi, где устранены уязвимости, связанные с неограниченным анализом внешних объектов XML. Эти уязвимости повлияли на внутреннюю обработку фреймворка и настраиваемые расширения. О некоторых из них мы поговорим далее.

XML-уязвимости Apache NiFi за последние 3 года

В частности, в релизе 1.20 устранена уязвимость CVE-2023-22832, связанная с неправильным ограничением ссылок на внешние объекты XML в процессоре ExtractCCDAAttributes, который извлекает информацию из FlowFile в формате Consolidated CDA и предоставляет отдельные атрибуты в виде атрибутов FlowFile. Ранее конфигурации потока, включающие процессор ExtractCCDAAttributes, были уязвимы для вредоносных XML-документов, содержащих объявления типа документа со ссылками на внешние XML-объекты. Эта уязвимость имела умеренный статус серьезности и устранена тем, что для процессора ExtractCCDAAttributes отключено объявления типа документа в конфигурации по умолчанию.

В релизе Apache NiFi 1.16.1 устранена уязвимость CVE-2022-29265, связанная с неправильным ограничением ссылок на внешние объекты XML в процессорах EvaluateXPath, EvaluateXQuery и ValidateXml. Эти процессоры разрешали ссылки на внешние сущности XML, если для них настроены значения свойств по умолчанию, что является уязвимостью с умеренным статусом серьезности. Как и в предыдущем случае, исправление отключает объявления типов документов в конфигурации по умолчанию для этих процессоров и запрещает разрешение внешних объектов XML в стандартных службах.

Помимо уязвимых процессоров, Standard Content Viewer также был подвержен атакам внешних XML-объектов при просмотре XML-документов с использованием форматированного выбора. Все эти компоненты были уязвимы при настройке с использованием значений свойств по умолчанию. Процессоры EvaluateXPath и EvaluateXQuery используют SAX для разбора входных документов, а ValidateXml использует StAX для чтения источников, подлежащих проверке. Стандартное средство просмотра содержимого также использовало StAX для источников ввода, а также компоненты JAXP XSLT для форматирования выходных документов.

Решение проблем с этими компонентами потребовало внедрения безопасных настроек для нескольких стилей обработки Java XML. Исправления в релизе Apache NiFi 1.16.1 включали полный рефакторинг XML-обработки, в т.ч. новый модуль обработки nifi-xml с дискретными компонентами для общих операций обработки Java XML. Этот подход позволил избежать ненужных зависимостей в nifi-security-utils и заменить служебные методы XmlUtils интерфейсами и стандартными реализациями, которые инкапсулируют операции для интерфейсов DOM, SAX, StAX и Validator. Так были устранены уязвимости, характерные для Standard Content Viewer, и добавил повторно используемые компоненты для обработки XSLT. Эта стратегия заменила прямые ссылки на интерфейсы JAXP доступом к компонентам, предоставленным в nifi-xml-processing, а также включила обычное тестирование уязвимостей.

На практике степень серьезности уязвимости CVE-2022-29265 зависела от конфигурации потока и источников обрабатываемых данных. Потоки, которые не используют EvaluateXPath, EvaluateXQuery или ValidateXml, менее уязвимы для атак во время выполнения. Однако, даже без этих процессоров потоки данных, обрабатывающие XML-объекты из ненадежных источников, по-прежнему были уязвимы для проблем со стандартным средством просмотра содержимого. Использование параметра форматирования для просмотра XML-содержимого FlowFile запускало неограниченную обработку, включая оценку внешних XML-сущностей. Благодаря всестороннему рефакторингу компонентов инфраструктуры и расширений в NiFi 1.16.1 от 2022 года эти проблемы были устранены.

А годом ранее, в Apache NiFi до выпуска 1.15.1 в процессоре TransformXML аутентифицированный пользователь мог настроить XSLT-файл, который мог раскрывать конфиденциальную информацию при наличии вызовов вредоносных внешних объектов. Хотя эта уязвимость CVE-2021-44145 и имела низкий уровень серьезности, для ее устранения разработчики Apache NiFi внесли изменения, чтобы свойство «Безопасная обработка» (Secure processing) применялось к настроенному XSLT-файлу, а также к изменяемым потоковым файлам. Исторически это свойство безопасной обработки для процессора TransformXml, нейтрализуя опасные XML-источники, было впервые представлено в NiFi 1.3.0. Однако, конфигурация не применялась к таблицам стилей XML, настроенным на основе имени XSLT-файла или свойств поиска. В обновленном процессоре TransformXml, который преобразует входной XML в новую выходную структуру на основе настроенного XSLT-источника с использованием Streaming API применялся метод XmlUtils для создания и настройки безопасных экземпляров XMLStreamReader. Хотя уязвимые XSLT-файлы можно было ввести при использовании сервиса поиска, проблема смягчалась из-за требования аутентифицированного доступа для настройки процессора TransformXml.

Под капотом улучшений: изменения Java-кода

Реализация безопасного подхода к обработке XML требует различных настроек в зависимости от используемого JAXP API. Стратегия реализации также зависит от версии Java среды выполнения и реализации JAXP. В частности, поддержка безопасной обработки XML в Java 7 более сложна, но Java 8 обеспечивает упрощенный подход при использовании стандартной реализации JAXP. Каждый JAXP API имеет связанный класс, который необходимо настроить, чтобы избежать потенциальных уязвимостей при обработке XML. Большинство классов конфигурации JAXP поддерживают функцию безопасного выполнения, которая отключает обработку внешних сущностей XML, а также устанавливает ограничения на потребление памяти. Компоненты StAX не поддерживают эту функцию, но их можно настроить.

Следующие классы управляют возможностями обработки XML, и любая ссылка на эти классы должна оцениваться для подтверждения безопасной реализации:

  • xml.parsers.DocumentBuilderFactory
  • xml.parsers.SAXParserFactory
  • xml.stream.XMLInputFactory
  • xml.transform.TransformerFactory
  • xml.validation.SchemaFactory
  • xml.validation.Validator
  • xml.validation.ValidatorHandler
  • xml.xpath.XPathFactory

Все эти компоненты, кроме StAX XMLInputFactory, поддерживают функцию безопасной обработки, определенную во флаге javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING. Вызов метода setFeature для поддерживающих классов с использованием флага функции следующим образом обеспечивает безопасную обработку:

factory.setFeature (XMLConstants.FEATURE_SECURE_PROCESSING, true);

Этого подхода достаточно для компонентов вне пакета javax.xml.stream при работе на Java 8 и последующих версиях с использованием стандартной реализации JDK.

Предоставление других реализаций JAXP через другие зависимости может изменить поведение во время выполнения. По этой причине дата-инженеру важно знать как исполняемую версию Java, так и исполняемую реализацию JAXP.

Без поддержки флага функции безопасной обработки для настройки компонентов StAX требуется установка дополнительных свойств в экземплярах XMLInputFactory до создания средств чтения XML. Свойство javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD поддерживает отключение ссылок на внешние объекты XML при установке значения в пустую строку. Свойство определяет, какие протоколы парсер может использовать для извлечения внешних ресурсов, а установка значения в пустую строку отключает все протоколы следующим образом:

factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");

В качестве альтернативы отключению внешнего доступа поддержку определения типа документа можно отключить с помощью свойства javax.xml.stream.XMLInputFactory.SUPPORT_DTD, а внешние объекты XML – с помощью свойства javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES. Установка значений свойства в false накладывает больше ограничений, чем отключение внешнего доступа из DTD, но обеспечивает более безопасную реализацию.

factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);

Модуль nifi-xml-processing включает следующие интерфейсы, соответствующие компонентам JAXP:

  • Document Object Model — org.apache.nifi.xml.processing.parsers.DocumentProvider
  • Extensible Stylesheet Language Transformations — org.apache.nifi.xml.processing.transform.TransformProvider
  • Simple API for XML — org.apache.nifi.xml.processing.sax.InputSourceParser
  • Streaming API for XML — org.apache.nifi.xml.processing.stream.XMLEventReaderProvider и org.apache.nifi.xml.processing.stream.XMLStreamReaderProvider
  • Validation — org.apache.nifi.xml.processing.validation.SchemaValidator

С каждым интерфейсом связана стандартная реализация, включающая функции и свойства, необходимые для обеспечения безопасной обработки. Стандартные классы совместимы с реализацией JAXP, связанной с JDK, и не требуют внешних зависимостей. Компоненты Java, настроенные для безопасной обработки, будут генерировать исключения при чтении XML, содержащего ссылки на внешние сущности. Класс исключения и сообщение будут различаться в зависимости от конкретного компонента JAXP, на который ссылаются, и каждый тип компонента будет генерировать исключение в соответствии с используемым API. Например, синтаксические анализаторы DOM и SAX будут генерировать исключение org.xml.sax.SAXParseException, а устройства чтения StAX будут генерировать исключение javax.xml.stream.XMLStreamException при обнаружении внешних ссылок.

Каталог ресурсов nifi-xml-processing включает ряд стандартных XML-файлов с внешними объектами и без них. Эти файлы обеспечивают простой способ подтверждения того, что каждый компонент JAXP имеет необходимые параметры конфигурации. Использование стандартного метода JUnit 5 assertThrows обеспечивает автоматическую проверку ожидаемого поведения синтаксического анализа при чтении внешних сущностей XML.

Компоненты в nifi-xml-processing генерируют обобщенное исключение ProcessingException, поэтому проверка причины исключения подтверждает ожидаемые результаты. Ниже показано ожидаемое поведение при попытке проанализировать поток XML, содержащий внешний объект:

ProcessingException e = assertThrows(ProcessingException.class, () -> provider.parse(stream));
assertInstanceOf(SAXParseException.class, e.getCause());

Статический анализ кода имеет некоторые ограничения с точки зрения возможностей обнаружения и осведомленности во время выполнения, но он обеспечивает полезный уровень оценки для обработки XML. К примеру, плагин SpotBugs Maven обеспечивает общий анализ кода и включает архитектуру плагинов для поддержки дополнительных функций. Плагин Find Security Bugs для SpotBugs включает анализаторы, способные обнаруживать уязвимости внешних сущностей XML для большинства компонентов JAXP. Хотя анализатор Find Security Bugs не может обнаруживать все типы уязвимостей внешних объектов XML, начиная с версии 1.12.0, он обеспечивает дополнительный уровень оценки компонентов XML в модуле nifi-xml-processing.

Настройка статического анализа в одном модуле не исключает возможности возникновения будущих проблем вне nifi-xml-processing, но обеспечивает базовый уровень проверки. В отличие от предыдущих методов в NiFi XmlUtils, большинство классов в рамках nifi-xml-processing не предоставляют прямого доступа к настраиваемым компонентам JAXP, что снижает вероятность неправильной настройки.

Таким образом, хотя Java 8 упростила шаги, необходимые для реализации безопасной обработки XML-документов, поддержка внешних объектов в Apache NiFi остается потенциальной уязвимостью. Однако, нововведения  релиза 1.16.1, включая специальный модуль и всесторонний обзор репозитория позволили сократить риски, связанные с обработкой внешних сущностей в XML-документах.

В продолжение темы безопасности Apache NiFi, читайте в нашей новой статье о безопасности взаимодействия с внешним API через SSL-соединение в процессоре InvokeHTTP. А про криптографическую защиту потока данных с помощью процессоров мы рассказываем здесь. Об уязвимостях, найденных и устраненных в 2023 году мы рассказываем в этом материале.

Как эффективно использовать Apache NiFi  для построения эффективных ETL-конвейеров потоковой аналитики больших данных, вы узнаете на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.

Источники

  1. https://exceptionfactory.com/posts/2022/05/31/analyzing-and-mitigating-xml-external-entity-vulnerabilities-in-apache-nifi/
  2. https://nifi.apache.org/security.html
Поиск по сайту