Валидация входных данных

Для начала работы с библиотекой Markdown-it необходимо установить пакет через npm:

npm install markdown-it

Подключение в проекте Node.js осуществляется следующим образом:

const MarkdownIt = require('markdown-it');
const md = new MarkdownIt();

В браузере можно использовать скрипт из CDN:

<script src="https://cdn.jsdelivr.net/npm/markdown-it/dist/markdown-it.min.js"></script>
<script>
  const md = window.markdownit();
</script>

Инициализация и основные методы

После создания экземпляра MarkdownIt доступны несколько ключевых методов:

  • md.render(markdownString) — преобразует строку Markdown в HTML.
  • md.renderInline(markdownString) — преобразует строку без обертки в блоки <p>.
  • md.set(options) — настраивает параметры парсера.

Пример использования:

const result = md.render('# Заголовок\n\nТекст **жирным** шрифтом');
console.log(result);
// Вывод:
// <h1>Заголовок</h1>
// <p>Текст <strong>жирным</strong> шрифтом</p>

Основные опции конфигурации

Markdown-it поддерживает множество опций, которые позволяют гибко настраивать парсер:

  • html — разрешает или запрещает HTML-теги в исходной строке (по умолчанию false).
  • linkify — автоматически превращает URL в кликабельные ссылки.
  • typographer — включает типографические преобразования (например, замену кавычек и тире).
  • breaks — преобразует переносы строк в <br>.

Пример:

const md = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  breaks: true
});

Плагины и расширения

Markdown-it поддерживает подключение плагинов, которые добавляют новые синтаксические конструкции или расширяют возможности парсинга.

Пример использования плагина markdown-it-emoji:

const emoji = require('markdown-it-emoji');
md.use(emoji);
console.log(md.render('I :heart: Markdown-it'));
// <p>I ❤️ Markdown-it</p>

Настройка рендеринга

Для тонкой настройки HTML-вывода можно переопределять рендереры отдельных токенов:

md.renderer.rules.strong_open = () => '<b>';
md.renderer.rules.strong_close = () => '</b>';
console.log(md.render('**Текст**'));
// <p><b>Текст</b></p>

Можно изменять рендеринг любого блока, включая заголовки, параграфы, списки и изображения.

Работа с токенами

Markdown-it сначала превращает исходный текст в токены, после чего рендерит их в HTML. Это позволяет анализировать структуру документа:

const tokens = md.parse('# Заголовок\n\nТекст', {});
tokens.forEach(token => {
  console.log(token.type, token.content);
});

Типы токенов:

  • heading_open / heading_close — открытие и закрытие заголовка.
  • paragraph_open / paragraph_close — открытие и закрытие параграфа.
  • inline — содержимое внутри блоков.

Валидация входных данных

Markdown-it не выполняет автоматическую проверку корректности входного Markdown. Для обеспечения безопасности и предотвращения XSS рекомендуется:

  1. Фильтрация HTML Если включена опция html: true, пользовательский ввод может содержать опасные теги. Для безопасного рендеринга применяют библиотеки, например DOMPurify:

    const DOMPurify = require('dompurify')(new JSDOM().window);
    const cleanHTML = DOMPurify.sanitize(md.render(userInput));
  2. Ограничение длин строк Для защиты от DoS-атак проверяют размер входного текста:

    if (userInput.length > 10000) throw new Error('Слишком длинный Markdown');
  3. Проверка типов данных Перед рендерингом необходимо убедиться, что на вход подается строка:

    if (typeof userInput !== 'string') throw new TypeError('Входные данные должны быть строкой');
  4. Валидация URL и ссылок Если включена опция linkify, можно дополнительно проверять корректность ссылок:

    const urlRegex = /^(https?:\/\/[^\s]+)$/;
    if (!urlRegex.test(userInput)) {
      console.warn('Некорректная ссылка в Markdown');
    }

Создание кастомных правил валидации

Markdown-it позволяет добавлять свои проверки через плагины. Например, ограничение на использование изображений:

function imageValidator(md) {
  const defaultRender = md.renderer.rules.image;
  
  md.renderer.rules.image = function(tokens, idx, options, env, self) {
    const src = tokens[idx].attrGet('src');
    if (!src.startsWith('https://')) return '';
    return defaultRender(tokens, idx, options, env, self);
  };
}

md.use(imageValidator);
console.log(md.render('![alt](http://example.com/image.png)')); // Пусто
console.log(md.render('![alt](https://example.com/image.png)')); // Рендерится

Такой подход позволяет интегрировать строгую валидацию контента на уровне рендеринга, что особенно важно при работе с пользовательским вводом.

Логирование и отладка

Для сложных документов полезно анализировать токены и их структуру:

const tokens = md.parse(userInput, {});
tokens.forEach(token => {
  console.log(`type: ${token.type}, tag: ${token.tag}, content: ${token.content}`);
});

Это облегчает выявление потенциально опасных или некорректных конструкций до этапа генерации HTML.

Итоговые рекомендации по безопасности

  • Всегда проверять, что входные данные — строка.
  • Ограничивать длину Markdown.
  • Применять DOMPurify или аналог для очистки HTML.
  • Ограничивать использование внешних ресурсов (ссылок, изображений).
  • При необходимости создавать кастомные правила через плагины Markdown-it для проверки специфических требований.

Эти меры позволяют использовать Markdown-it безопасно и надежно в любых приложениях, обрабатывающих данные пользователей.