Санитизация HTML содержимого

Tippy.js позволяет создавать всплывающие подсказки и тултипы с высокой степенью гибкости, включая возможность отображения HTML-контента внутри тултипов. При использовании HTML-контента важно учитывать вопросы безопасности, чтобы избежать уязвимостей XSS (Cross-Site Scripting). Для этого Tippy.js предоставляет встроенные механизмы и рекомендации по санитизации HTML.


Включение HTML-контента

По умолчанию Tippy.js принимает текстовые значения через опцию content. Для HTML-контента необходимо использовать свойство allowHTML:

tippy('#myButton', {
  content: '<strong>Важная подсказка</strong>',
  allowHTML: true
});
  • allowHTML: true — разрешает вставку HTML-кода.
  • Без включения allowHTML все HTML-теги будут экранированы, что предотвращает потенциальные XSS-атаки.

Риски вставки HTML

Использование allowHTML: true открывает возможность выполнения вредоносного кода, если содержимое берется из ненадежных источников. Например:

const userContent = '<img src=x oner ror=alert("XSS")>';
tippy('#userButton', {
  content: userContent,
  allowHTML: true
});

В этом случае злоумышленник может внедрить JavaScript, который выполнится в контексте страницы.


Методы безопасной вставки HTML

  1. Ручная санитизация с помощью библиотек Рекомендуется использовать сторонние библиотеки для очистки HTML, например DOMPurify:
import DOMPurify from 'dompurify';

const unsafeContent = '<img src=x oner ror=alert("XSS")>';
const safeContent = DOMPurify.sanitize(unsafeContent);

tippy('#secureButton', {
  content: safeContent,
  allowHTML: true
});
  • DOMPurify.sanitize() удаляет скрипты, onerror и другие опасные атрибуты.
  • Позволяет сохранять полезное форматирование (теги <strong>, <em>, <a> и др.) без угрозы безопасности.
  1. Использование DOM-элементов вместо строк Tippy.js позволяет передавать DOM-узлы в content, что снижает риск внедрения скриптов:
const tooltipNode = document.createElement('div');
tooltipNode.innerHTML = '<strong>Безопасная подсказка</strong>';

tippy('#domButton', {
  content: tooltipNode,
  allowHTML: true
});
  • Контент создается в DOM заранее, что позволяет контролировать содержимое.
  • Можно комбинировать с DOMPurify для динамического контента.

Настройка безопасности через interactive и appendTo

Tippy.js предоставляет дополнительные опции, влияющие на обработку HTML:

  • interactive: true — позволяет пользователю взаимодействовать с HTML-контентом, например кликать по ссылкам или кнопкам внутри тултипа.
  • appendTo: document.body — рекомендуемое значение для сложных HTML-структур, чтобы тултип не наследовал стили или скрипты из родительских контейнеров.

Пример безопасной комбинации:

tippy('#interactiveButton', {
  content: DOMPurify.sanitize('<a href="#">Ссылка</a>'),
  allowHTML: true,
  interactive: true,
  appendTo: document.body
});

Санитизация при динамическом обновлении контента

Tippy.js позволяет обновлять контент тултипа после инициализации через метод .setContent():

const tip = tippy('#dynamicButton', {
  content: '',
  allowHTML: true
});

function updateTooltip(userInput) {
  const sanitized = DOMPurify.sanitize(userInput);
  tip[0].setContent(sanitized);
}
  • Каждое новое значение обязательно должно проходить санитизацию, если оно приходит от пользователя.
  • Это предотвращает появление вредоносного HTML при обновлении тултипа.

Дополнительные рекомендации

  1. Ограничение тегов и атрибутов DOMPurify позволяет настраивать разрешённые теги и атрибуты:
DOMPurify.sanitize(unsafeContent, {
  ALLOWED_TAGS: ['b', 'i', 'strong', 'em', 'a'],
  ALLOWED_ATTR: ['href', 'title']
});
  1. Контроль ссылок Для ссылок <a> рекомендуется добавлять rel="noopener noreferrer" и target="_blank" при необходимости.

  2. Избегание inline-скриптов Никогда не вставлять содержимое с тегами <script> или атрибутами типа on*.


Итоговая структура безопасного HTML в Tippy.js

  • allowHTML: true — разрешает HTML.
  • Санитизация через DOMPurify для пользовательского или динамического контента.
  • Использование DOM-узлов при возможности.
  • Опции interactive и appendTo для сложных тултипов.
  • Постоянное обновление и проверка контента через .setContent() с санитизацией.

Эти подходы обеспечивают баланс между функциональностью HTML в тултипах и безопасностью приложения, предотвращая внедрение вредоносного кода.