
MISP <= 2.5.27 - Хранимая межсайтовая уязвимость (XSS) через Workflow Engine (doT.js Template Injection).
MISP <= 2.5.27 — Межсайтовый скриптинг (XSS) с сохранением через движок рабочих процессов (внедрение шаблонов doT.js)
Обнаружен Franck FERMAN
Обзор - Корневая причина - Цепочка атаки - Структура - Использование - Устранение - Ссылки
CVE-2025-67906 (GCVE-1-2025-0031) — уязвимость межсайтового скриптинга с сохранением (Stored XSS) в MISP (Malware Information Sharing Platform) версиях до 2.5.27 включительно.
Уязвимость находится в app/View/Elements/Workflows/executionPath.ctp, компоненте отображения пути выполнения рабочего процесса. Поле name триггеров рабочего процесса сохраняется в базу данных без серверной очистки и затем отображается в DOM через шаблонизатор doT.js без экранирования HTML. Аутентифицированный злоумышленник может внедрить произвольный HTML/JavaScript, который выполняется в браузере любого пользователя, просматривающего скомпрометированный рабочий процесс.
Поскольку полезная нагрузка сохраняется в базе данных и отображается при каждой загрузке страницы, XSS является постоянным — он переживает обновления страницы, затрагивает нескольких пользователей и сохраняется до тех пор, пока рабочий процесс не будет явно удален.
Обнаружение: Эта уязвимость была выявлена и ответственно раскрыта Franck FERMAN.
Существует несколько оценок CVSS для данной уязвимости:
| Источник | Балл | Степень опасности | Вектор |
|---|---|---|---|
| NIST NVD | 9.0 | Критическая | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H |
| GCVE (CIRCL) | 7.1 | Высокая | CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:A/VC:H/VI:N/VA:N/SC:H/SI:H/SA:H |
| CNA (MITRE) | 5.4 | Средняя | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N |
Расхождение в баллах отражает разные оценки глубины воздействия. Оценка NIST NVD (9.0) учитывает полное воздействие на конфиденциальность, целостность и доступность, поскольку полезная нагрузка XSS выполняется с привилегиями сессии жертвы, что позволяет эксплуатировать данные на уровне администратора и манипулировать рабочими процессами. Оценка CNA (5.4) учитывает только ограниченное воздействие на C/I для обычного XSS. Оценка GCVE CVSS 4.0 (7.1) включает требования к атаке (привилегии) и модификаторы активного взаимодействия с пользователем.
Область действия во всех оценках изменена, поскольку полезная нагрузка злоумышленника (внедренная через API MISP) выполняется в другом контексте безопасности (браузер жертвы).
Движок рабочих процессов MISP позволяет аутентифицированным пользователям создавать и редактировать рабочие процессы через REST API. Модель данных рабочего процесса включает компонент trigger с полем name. Это поле:
doT.js — это быстрый JavaScript-шаблонизатор. Он использует {{= }} для интерполяции, которая не экранирует HTML по умолчанию. Редактор рабочих процессов MISP использует doT.js для рендеринга метаданных триггера (включая поле name) в DOM. Когда поле name содержит HTML, например ``, шаблонизатор вставляет его как необработанный HTML, и браузер выполняет встроенный JavaScript.
Исправление требует одного из следующих действий:
{{! }}, который экранирует HTML-значениеPOST /workflows/edit/{id}
{
"Workflow": {
"id": "1",
"data": "{\"1\":{\"data\":{\"name\":\"\"}}}"
}
}
Значение name внутри поля data JSON является точкой внедрения. Весь граф рабочего процесса сериализуется как JSON-строка в теле запроса.
Уязвимость усиливается архитектурным выбором использования клиентского шаблонизатора (doT.js) для рендеринга визуального редактора рабочих процессов. Редактор рабочих процессов — это графический интерфейс перетаскивания, где каждый триггер/действие отображается в виде визуального блока. Поле name триггера отображается как метка внутри этих графических блоков.
doT.js строит визуальные компоненты, генерируя строки HTML из шаблонов и вставляя их в DOM. Синтаксис интерполяции {{= }} создает неэкранированный вывод — любые данные, интерполированные в шаблон, рассматриваются как разметка, а не как текст. Если бы то же поле name отображалось через element.textContent (который трактует ввод как обычный текст) или через синтаксис экранированного вывода doT.js {{! }}, XSS был бы невозможен независимо от содержимого ввода.
Поверхность атаки существует именно потому, что:
{{= }}) для производительностиname, интерпретируется браузером как HTMLЭто распространенный шаблон уязвимости в веб-приложениях, использующих клиентские шаблонизаторы для создания интерактивных визуальных интерфейсов: потребность в богатом рендеринге создает неявное доверие между шаблоном и его источниками данных, и любой неочищенный пользовательский ввод, попадающий в шаблон, становится исполняемым кодом.
<script>Необработанный тег <script>, внедренный через интерполяцию шаблона, обычно не выполняется в этом контексте. Браузеры не запускают элементы <script>, вставленные в DOM после первоначального разбора страницы (через innerHTML или аналоги). Атрибуты обработчиков событий, такие как onerror, onload или onmouseover на HTML-элементах, обходят это ограничение, поскольку они запускают встроенный JavaScript при обработке браузером атрибутов элемента, независимо от способа вставки элемента.
Вектор <img src="https://raw.githubusercontent.com/franckferman/cve-2025-67906/HEAD/x" onerror="..."> предпочтительнее, потому что:
src="x" гарантирует немедленную ошибку загрузки, вызывая onerror без взаимодействия с пользователемscript-src, которые блокируют встроенные теги <script>, так как выполнение происходит через обработчик событий на элементе, не являющемся скриптомЭкземпляры MISP обычно развертывают заголовки Content Security Policy, которые ограничивают connect-src, предотвращая вызовы fetch() и XMLHttpRequest к внешним источникам. Полезные нагрузки эксфильтрации в этом PoC обходят CSP, используя window.location (навигацию) вместо API-вызовов: