Библиотека Marked предназначена для парсинга Markdown в HTML и широко используется в веб-приложениях. Одной из ключевых проблем при работе с пользовательским вводом является безопасность HTML, поскольку некорректная обработка может привести к XSS-уязвимостям. Санитизация HTML позволяет контролировать, какие теги и атрибуты разрешены в выходном HTML.
По умолчанию Marked поддерживает встроенный HTML в Markdown. Это
означает, что конструкции вроде текст
будут корректно преобразованы и отображены как HTML.
Для контроля этой функции используется опция:
marked.setOptions({
gfm: true, // поддержка GitHub Flavored Markdown
breaks: false, // переносы строк
sanitize: false, // устаревшая опция
headerIds: true
});
Внимание: опция
sanitizeустарела начиная с Marked v1.0 и больше не используется для полной безопасности. Для надежной защиты требуется внешняя библиотека санитизации.
DOMPurifyДля безопасной работы с HTML на клиенте или сервере рекомендуется использовать библиотеки вроде DOMPurify:
import DOMPurify from 'dompurify';
import { marked } from 'marked';
const markdown = `# Пример\nопасный HTML`;
const html = marked(markdown);
const cleanHTML = DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'ul', 'ol', 'li', 'code', 'pre'],
ALLOWED_ATTR: ['href', 'title']
});
В этом примере:
on* атрибуты или
jav * ascript: ссылки.Использование DOMPurify гарантирует, что даже если Markdown содержит
, этот код будет
удален при рендеринге.
На сервере (Node.js):
import { marked } from 'marked';
import DOMPurify from 'dompurify';
import { JSDOM } from 'jsdom';
const window = new JSDOM('').window;
const DOMPurifyServer = DOMPurify(window);
const markdown = 'Пример
';
const html = marked(markdown);
const safeHTML = DOMPurifyServer.sanitize(html);
Особенности:
jsdom позволяет
использовать DOMPurify на сервере.На клиенте (браузер):
const html = marked(userInputMarkdown);
const cleanHTML = DOMPurify.sanitize(html);
document.getElementById('content').innerHTML = cleanHTML;
Marked позволяет создавать пользовательский рендерер, чтобы контролировать вывод HTML:
const renderer = new marked.Renderer();
renderer.link = (href, title, text) => {
const safeHref = DOMPurify.sanitize(href, { ALLOWED_URI_REGEXP: /^(https?:)?\/\// });
return `${text}`;
};
marked.setOptions({ renderer });
Такой подход:
jav * ascript: или data: схемы.sanitize. Она не обеспечивает безопасную обработку
HTML.,
, ) могут быть разрешены
или запрещены в зависимости от политики безопасности.
- Инлайновые элементы (
,
, ,
) обычно безопасны и разрешены.
- Скриптовые и потенциально опасные элементы
(
, ,
) должны полностью блокироваться.
- Ссылки и изображения требуют проверки схем
(
http, https) и удаления
jav * ascript: ссылок.
7. Интеграция с фреймворками
В React или Vue рекомендуется использовать
dangerouslySetInnerHTML / v-html только с
предварительной санитизацией через DOMPurify:
// React
// Vue
Это предотвращает внедрение XSS через Markdown-контент, загруженный
из внешних источников.