Защита от инъекций

Intro.js — это легковесная библиотека JavaScript, предназначенная для создания интерактивных пошаговых туров по веб-приложению. Она позволяет выделять элементы интерфейса, добавлять подсказки и управлять последовательностью действий пользователя. Тур создаётся на основе HTML-атрибутов и JavaScript-конфигурации, что делает интеграцию гибкой и наглядной.

Ключевые функции библиотеки включают:

  • Выделение DOM-элементов с помощью подсветки.
  • Возможность создавать последовательность шагов с описанием.
  • Поддержка кастомизации стилей и позиции подсказок.
  • Обработка событий начала и завершения тура.

Подключение и инициализация

Для использования Intro.js необходимо подключить библиотеку через CDN или локальный файл:

<link rel="stylesheet" href="https://unpkg.com/intro.js/minified/introjs.min.css">
<script src="https://unpkg.com/intro.js/minified/intro.min.js"></script>

После подключения создаётся объект тура и задаются шаги:

const intro = introJs();
intro.setOptions({
  steps: [
    { 
      element: '#step1', 
      intro: 'Описание первого шага', 
      position: 'bottom' 
    },
    { 
      element: '#step2', 
      intro: 'Описание второго шага', 
      position: 'right' 
    }
  ],
  showBullets: true,
  showStepNumbers: true,
  exitOnOverlayClick: false
});
intro.start();

Пояснение параметров:

  • element — CSS-селектор элемента, к которому привязан шаг.
  • intro — текст подсказки.
  • position — позиция подсказки относительно элемента (top, bottom, left, right).
  • showBullets — отображение навигационных точек.
  • exitOnOverlayClick — управление возможностью выхода при клике на затемнённую область.

Безопасность и защита от инъекций

При работе с библиотеками, которые динамически вставляют контент в DOM, необходимо учитывать опасность XSS-атак. Intro.js позволяет задавать текст подсказок через опцию intro, которая может содержать HTML. Если этот текст формируется на основе пользовательского ввода, появляется риск внедрения вредоносного кода.

Очистка пользовательского ввода

Чтобы предотвратить инъекции, следует использовать методы очистки данных перед вставкой в Intro.js:

function escapeHtml(text) {
  const map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };
  return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}

const userInput = '<script>alert("XSS")</script>';
intro.setOptions({
  steps: [
    { element: '#step1', intro: escapeHtml(userInput), position: 'top' }
  ]
});

В этом примере все специальные символы заменяются на HTML-сущности, предотвращая выполнение скриптов.

Использование текстового режима

Intro.js поддерживает опцию tooltipClass и вставку контента через текстовый формат без HTML:

intro.setOptions({
  steps: [
    { element: '#step1', intro: document.createTextNode(userInput).textContent }
  ]
});

Это гарантирует, что любые HTML-теги будут восприниматься как текст, а не как элементы DOM.

Ограничение динамических данных

Для безопасного отображения подсказок рекомендуется заранее определять список разрешённых сообщений (whitelist) вместо вставки произвольных пользовательских данных.

const allowedMessages = {
  step1: 'Добро пожаловать на первый шаг',
  step2: 'Следующий элемент интерфейса'
};

intro.setOptions({
  steps: [
    { element: '#step1', intro: allowedMessages.step1, position: 'bottom' },
    { element: '#step2', intro: allowedMessages.step2, position: 'right' }
  ]
});

Такой подход полностью исключает возможность XSS через контент Intro.js.

События и дополнительная безопасность

Intro.js предоставляет события для контроля состояния тура: onbeforechange, onchange, onexit, oncomplete. Использование этих событий позволяет проверять и валидировать данные перед отображением подсказок:

intro.onbeforechange(function(targetElement) {
  const content = targetElement.getAttribute('data-intro');
  if (/</.test(content)) {
    targetElement.setAttribute('data-intro', escapeHtml(content));
  }
});

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

Рекомендации по защите

  • Никогда не вставлять сырые пользовательские данные в параметр intro.
  • Всегда использовать функции экранирования HTML для текста подсказок.
  • Предпочтительно использовать заранее определённые сообщения или whitelist.
  • Применять события Intro.js для валидации и очистки контента на лету.
  • Минимизировать использование HTML в подсказках, отдавая предпочтение чистому тексту.

Эти меры гарантируют безопасное использование Intro.js в любых веб-приложениях без риска инъекций и XSS-атак.