Popper.js в первую очередь предназначен для управления всплывающими элементами, такими как тултипы, выпадающие меню, подсказки и модальные окна. Основная задача библиотеки — динамически позиционировать элементы относительно целевых объектов на странице, учитывая размеры, прокрутку и видимость. Однако при этом возникают потенциальные уязвимости, связанные с XSS (Cross-Site Scripting), особенно если содержимое всплывающих элементов формируется динамически из пользовательского ввода.
innerHTML:const tooltip = document.createElement('div');
tooltip.innerHTML = userInput; // userInput приходит с сервера
new Popper(referenceElement, tooltip, {
placement: 'top'
});
Если userInput не фильтруется, злоумышленник может
вставить <script> или другие вредоносные элементы,
которые выполнятся при отображении тултипа.
tooltip.innerHTML = `<strong>${userInput}</strong>`;
Любой HTML, переданный в userInput, будет вставлен
напрямую в DOM.
innerHTML. Простое преобразование специальных
символов:function escapeHTML(str) {
const div = document.createElement('div');
div.appendChild(document.createTextNode(str));
return div.innerHTML;
}
tooltip.innerHTML = escapeHTML(userInput);
textContent и innerText полностью
предотвращают исполнение HTML:tooltip.textContent = userInput;
Применение шаблонов через безопасные библиотеки Библиотеки вроде DOMPurify или Handlebars автоматически фильтруют ввод и позволяют безопасно вставлять HTML.
Контроль источников данных Любые данные от пользователя, сервера или внешних API должны проверяться и фильтроваться до вставки в Popper-элементы. Особенно это касается динамических тултипов и меню.
appendTo и кастомных контейнеров позволяет
создавать всплывающие элементы вне основного DOM, что усложняет
внедрение фильтров при неправильной архитектуре.textContent для
динамического текста, если нет строгой необходимости в
HTML.import { createPopper } from '@popperjs/core';
import DOMPurify from 'dompurify';
const tooltip = document.createElement('div');
tooltip.classList.add('tooltip');
// Безопасная вставка HTML
tooltip.innerHTML = DOMPurify.sanitize(userInput);
const popperInstance = createPopper(referenceElement, tooltip, {
placement: 'right',
modifiers: [
{
name: 'offset',
options: { offset: [0, 8] },
},
],
});
Использование DOMPurify.sanitize предотвращает
выполнение скриптов, при этом сохраняя допустимый форматированный
контент.
XSS в Popper.js не является багом самой библиотеки — это следствие
неправильной работы с DOM. Любой динамический контент требует тщательной
очистки и контроля источников данных. Комбинация
textContent или безопасного HTML через
sanitizers, строгий контроль пользовательских данных и
применение CSP формируют надежный барьер против внедрения скриптов в
всплывающие элементы.