FlawOpen

flawopen.com/XSS/Renderização de Markdown

Markdown é seguro contra XSS?

Guia de referência
Resposta curta

Trate o HTML gerado a partir de Markdown como conteúdo não confiável. Um parser pode preservar HTML bruto porque a sintaxe permite isso; converter Markdown não sanitiza a saída. Pense no parser como um tradutor que copia fielmente a marcação, não como um guarda de segurança.

Onde fica o limite de confiança

A especificação CommonMark define que HTML bruto com formato de tag é renderizado sem escape. O comportamento real depende do parser, das opções, dos plugins e do framework. O Marked, por exemplo, avisa explicitamente que não sanitiza o HTML gerado. A sintaxe Markdown não comprova que a entrada é segura; o sanitizador precisa corresponder ao destino final do HTML.

Fluxo seguro de renderização

INSEGURO — renderizar e inserir saída não confiável
const html = marked.parse(userMarkdown);
container.innerHTML = html; // saída do parser não foi sanitizada
PROTEGIDO — sanitizar antes do destino HTML
import DOMPurify from "dompurify";

const html = marked.parse(userMarkdown);
container.innerHTML = DOMPurify.sanitize(html, {
  USE_PROFILES: { html: true }
});

O exemplo usa o perfil somente HTML do DOMPurify porque esta visualização não precisa de SVG ou MathML. Escolha o menor conjunto de recursos necessário. Não altere a marcação sanitizada nem a passe por outra biblioteca que transforme HTML antes da inserção: isso pode invalidar as garantias. Prefira a renderização segura de texto do framework quando HTML rico não for necessário. Use Content Security Policy e Trusted Types como defesa adicional, não como substitutos da sanitização.

Revisão de produção

Perguntas frequentes

Desativar HTML bruto torna Markdown seguro?

Isso remove um recurso de entrada, mas não comprova segurança por si só. Revise links, imagens, extensões, o HTML gerado e o contexto final; sanitize a saída ao inseri-la como HTML.

Posso modificar o HTML depois de sanitizá-lo?

Evite. Alterações posteriores podem introduzir marcação insegura ou invalidar as decisões do sanitizador. Faça as transformações antes e sanitize por último.

O DOMPurify torna toda saída segura em qualquer contexto?

Não. Use-o para fragmentos HTML conforme o modelo de ameaças documentado, mantenha-o atualizado, adote uma política restrita e não reutilize a saída em contextos como strings JavaScript ou CSS.

Referências

Veja também Cross-Site Scripting (XSS, CWE-79): como funciona e como evitar em todas as linguagens — flawopen.com Svelte é seguro contra XSS por padrão? Upload de SVG pode causar XSS? Risco de XSS no Vue v-html WKWebView: HTML não confiável é seguro? XSS refletido, armazenado e baseado em DOM: quais são as diferenças? Riscos de segurança do addJavascriptInterface no Android