XSL (Extensible Stylesheet Language) — это язык для преобразования документов XML. XSLT означает XSL Transformations. XSL Transformations — это сами XML-документы. Результатом преобразования может быть другой XML-документ или что-то еще, например, документ HTML, файл CSV или текстовый файл. В этой статье я расскажу о нескольких векторах атаки на XSLT. Уязвимости в языке стилей (XSLT) могут иметь серьезные последствия для веб-приложений, зачастую приводящих к удаленному выполнению кода (RCE). Примерами уязвимостей XSLT для удаленного выполнения кода с общедоступными эксплойтами являются CVE-2012-5357, CVE-2012-1592, CVE-2005-3757. Из приведенных выше примеров видно, что уязвимости XSLT известны довольно давно, и, хотя они менее распространены, чем другие подобные уязвимости, такие как XML Injection, они несут довольно серьезные угрозы безопасности.  Обычное использование XSLT — это преобразование данных между форматами файлов, обрабатываемыми различными приложениями, а также в качестве механизма шаблонов. Многие бизнес-приложения широко используют XSLT. Например, у нас есть XML-документ с какими-то элементами, атрибутами и значениями, но нам для работы требуется переместить элементы, изменить структуру (к примеру, атрибут сделать элементом) или выполнить дополнительные расчеты. Для можно воспользоваться XSLT-процессором и преобразовать старый документ в новый вид. Эта технология часто используется для следующих целей: Функциональность современных XSLT-процессоров имеет огромный недостаток: если они не настроены должным образом, XSLT-процессоры могут ставить под угрозу веб-приложение или позволить выполнять произвольный код. Пример трансформации данных: У нас есть XML-файл, который содержит список фруктов и относительных описаний:  Чтобы преобразовать XML-документ в текстовый файл, мы можем использовать следующее преобразование XSL: В результате получим plain-text файл: В примерах мы cфокусируемся на уязвимом приложении, использующем Microsoft’s System.Xml XSL; однако подобные методы применяются к другим распространенным библиотекам, таким как Libxslt, Saxon и Xalan. Первым шагом является определение уязвимых параметров приложения. Самый простой случай — это приложение, которое позволяет загружать произвольный файл XSLT. Препроцессор может генерировать XML-документ динамически, используя инпуты пользователя без надлежащей проверки (поле Your Company Name Here): Чтобы определить, является ли приложение уязвимым, достаточно ввести символы, которые обычно недействительны для синтаксиса XML-документа, например двойные кавычки, одинарные кавычки и угловые скобки. Если сервер возвращает ошибку, приложение потенциально уязвимо.  В разных библиотеках реализованы разные функции XSLT, а функция, доступная в одной библиотеке, может быть недоступна в другой. Очень часто внедряются проприетарные расширения, которые несовместимы между библиотеками. Кроме того, параметры по умолчанию широко изменяются между реализациями, как правило, с более старыми библиотеками, в которых есть опасные функции, включенные по умолчанию, и более новые библиотеки, требующие от разработчиков явно включать их, когда это необходимо. Имя поставщика библиотеки можно получить с помощью функции «system-property ()», которая является частью стандарта XSLT v1.0. Следующее преобразование может быть использовано для определения «поставщика» библиотеки: Мы тестируем реализацию Microsoft .Net System.xml, поэтому возвращаемое значение — «Microsoft»: В таблице представлена обработка system-property препроцессоров XSLT:  В следующем примере мы используем внешний объект для чтения содержимого файла «C:\secretfruit.txt». Элемент ENTITY помещает содержимое файла в ссылку «ext_file», которую мы затем печатаем внутри основного документа, используя «ext_file;». Вывод показывает секретное содержимое файла (Golden Apple): Этот метод можно использовать для извлечения файлов, хранящихся локально на веб-сервере, и веб-страниц, размещенных на внутренних системах, которые обычно не могут быть доступны злоумышленнику. Это могут быть файлы конфигурации, содержащие учетные данные или файлы, содержащие другую конфиденциальную информацию. Файлы также можно извлекать с использованием UNC-путей: \servername\share\file и http://servername/file. Используя список IP-адресов и номеров портов, также можно определить, открыт или закрыт удаленный порт в зависимости от ответа приложения. Например, приложение может отображать различные сообщения об ошибках или содержать временные задержки в ответе. Следующее преобразование XSLT использует URL-адрес http://172.16.132.1:25 вместо локального пути к файлу, используемого в предыдущем примере: На следующем скриншоте показана ошибка, возвращаемая при попытке подключения к URL-адресу.   Функция «document ()» также может использоваться для извлечения документов и для выполнения сканирования портов: Встроенные блоки сценариев являются проприетарными расширениями XSLT, которые позволяют включать код непосредственно в документ XSLT. В реализации Microsoft, например, может быть включен код C #. Когда документ анализируется, код компилируется и выполняется удаленным сервером. Следующий документ XSLT выводит информацию о файлах в текущем рабочем каталоге: Сначала мы определяем два новых XML-префикса внутри тега «xsl: stylesheet». Первый «xmlns: msxsl» необходим для включения проприетарных расширений Microsoft, второй «xmlns: user» объявляет пользовательское расширение пользователя, которое реализуется блоком сценариев «msxsl: script». Код C # реализует функцию «execute ()», которая выполняет команду «cmd.exe / c dir» и возвращает вывод команды в виде строки. Наконец, функция вызывается внутри тега «xsl: value-of». Результатом преобразования является вывод команды «dir»: В следующем примере показана экспулатация XSS вектора в теге template: Теги импорта и инклуда приложений могут использоваться для объединения нескольких документов XSLT.
Функции импорта могут использоваться для объединения документа XSLT с внешним документом. Когда загружается внешний файл, весь документ анализируется, и если атакующий контролирует его, он может использовать как внешние внешние объекты XML, так и встроенные скрипты во внешнем файле. Тег «xsl: import» можно использовать только в качестве первого дочернего элемента тега «xsl: stylesheet», в то время как тег «xsl: include» может использоваться в других позициях. Мы хотим включить следующий внешний XSLT-файл с именем «external_transform.xslt» с сообщением (Hello from the external transformation):  Чтобы включить внешний документ, нам нужно использовать следующий тег: Здесь есть одна особенность: тег «xsl: include» не может быть включен в тег «xsl: template». Поэтому нам сначала нужно закрыть тег «xsl: template», тогда мы можем добавить тег «xsl: include», который удовлетворяет первому требованию. Чтобы получить верно сформированный XML-файл, нам нужно снова открыть тег «xsl: template» после тега «xsl: include». После внедрения инъекции полученный XSLT-документ выглядит следующим образом: Если ваше приложение использует XSLT, вы можете уменьшить риски, следуя этим рекомендациям:
По возможности избегайте предоставленных пользователем XSLT-документов. Не генерируйте XSLT-документы со значениями, передающимися из ненадежных источников (инпутов). Если требуется нестатическое значение, оно должно быть включено в файл данных XML и только ссылаеться на документ XSLT.  Отключите потенциально опасную функциональность, реализованную используемой библиотекой XSLT. Библиотеки часто используют небезопасные значения по умолчанию. Проверьте документацию библиотеки чтобы отключить: внешние XML-объекты; функцию «document ()»; теги импорта и включения. Используйте защитные средства фильтрации передаваемого контента. Также прикладываю таблицу потенциально опасных точек препроцессоров XSLT, используемых по умолчанию:  информационная опасность