Markdown-it — это высокопроизводительная библиотека для парсинга Markdown в HTML. При её использовании критически важно учитывать уязвимости XSS (Cross-Site Scripting) и возможность внедрения вредоносного кода через пользовательский ввод. По умолчанию Markdown-it не фильтрует HTML-теги, что открывает потенциал для атак. Любой HTML, включённый в Markdown, будет напрямую вставлен в итоговый HTML-код.
Для снижения риска XSS следует отключать обработку встроенного HTML,
если она не требуется. В Markdown-it это делается через опцию
html:
const md = require('markdown-it')({
html: false, // блокировка встроенного HTML
linkify: true,
typographer: true
});
html: false запрещает вставку HTML-тегов.linkify: true автоматически превращает URL в
ссылки.typographer: true включает преобразование
типографических символов.Markdown часто содержит внешние ссылки. Чтобы предотвратить
фишинг и небезопасные ссылки, важно добавлять атрибуты
rel="noopener noreferrer" и target="_blank".
Markdown-it позволяет переопределять рендереры через правила:
const defaultRender = md.renderer.rules.link_open || function(tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options);
};
md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
const aIndex = tokens[idx].attrIndex('target');
if (aIndex < 0) {
tokens[idx].attrPush(['target', '_blank']);
} else {
tokens[idx].attrs[aIndex][1] = '_blank';
}
const relIndex = tokens[idx].attrIndex('rel');
if (relIndex < 0) {
tokens[idx].attrPush(['rel', 'noopener noreferrer']);
} else {
tokens[idx].attrs[relIndex][1] = 'noopener noreferrer';
}
return defaultRender(tokens, idx, options, env, self);
};
Это гарантирует, что все внешние ссылки будут открываться в новой
вкладке безопасно, предотвращая доступ к объекту
window.opener.
Если включён HTML, необходимо использовать сильные HTML-саниайзеры, такие как DOMPurify:
const DOMPurify = require('dompurify')(new JSDOM('').window);
const unsafeHTML = md.render(userInput);
const safeHTML = DOMPurify.sanitize(unsafeHTML);
Это предотвращает внедрение <script>,
<iframe> и других опасных элементов.
DOMPurify позволяет тонко настраивать список разрешённых тегов и атрибутов. Например:
const safeHTML = DOMPurify.sanitize(unsafeHTML, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'ul', 'ol', 'li', 'code', 'pre'],
ALLOWED_ATTR: ['href', 'title', 'target', 'rel']
});
Это исключает любые нестандартные или потенциально опасные элементы.
jav * ascript: или других
небезопасных протоколов.Markdown-it поддерживает плагины, но они могут быть источником уязвимостей. Рекомендации:
Для защиты системы важно вести логирование обработанных Markdown-документов и мониторить аномальные или потенциально вредоносные паттерны:
<script> или
<iframe> в пользовательском контенте.Markdown-it предоставляет гибкий инструмент для преобразования Markdown в HTML, однако безопасность полностью зависит от настройки и фильтрации контента. Контроль HTML, рендеринг ссылок, использование саниайзеров, ограничение пользовательского ввода и осторожная работа с плагинами — ключевые меры для предотвращения XSS и других атак.
Эти практики создают безопасную среду при работе с Markdown, минимизируя возможность эксплуатации уязвимостей через пользовательский ввод.