flawopen.com/XSS/Markdown-Rendering
Ist Markdown-Rendering vor XSS sicher?
Behandle aus Markdown erzeugtes HTML als nicht vertrauenswürdig. Ein Parser kann rohes HTML übernehmen, weil die Syntax es erlaubt; die Markdown-Konvertierung bereinigt die Ausgabe nicht. Der Parser ist ein Übersetzer für Markup, kein Sicherheitsfilter.
Wo die Vertrauensgrenze liegt
Die CommonMark-Spezifikation sieht vor, dass tagförmiges rohes HTML ohne Escaping ausgegeben wird. Das tatsächliche Verhalten hängt von Parser, Optionen, Plugins und Framework ab. Marked weist ausdrücklich darauf hin, dass es das erzeugte HTML nicht bereinigt. Markdown-Syntax belegt nicht, dass die Eingabe sicher ist; der Sanitizer muss den endgültigen HTML-Sink schützen.
Sicherer Rendering-Ablauf
const html = marked.parse(userMarkdown); container.innerHTML = html; // Parserausgabe nicht bereinigt
import DOMPurify from "dompurify";
const html = marked.parse(userMarkdown);
container.innerHTML = DOMPurify.sanitize(html, {
USE_PROFILES: { html: true }
});
Das Beispiel nutzt DOMPurifys reines HTML-Profil, weil diese Ansicht weder SVG noch MathML benötigt. Beschränke den Funktionsumfang auf den tatsächlichen Bedarf. Verändere bereinigtes Markup nicht und reiche es vor dem Einfügen nicht durch eine weitere HTML-verändernde Bibliothek; dadurch können die Garantien entfallen. Wenn kein Rich-HTML nötig ist, nutze die sichere Textausgabe des Frameworks. Content Security Policy und Trusted Types sind zusätzliche Schutzschichten, kein Ersatz für Sanitizing.
Prüfpunkte für den Produktivbetrieb
- ✓Fixiere die Markdown-Parser-Version und prüfe Optionen für rohes HTML, Plugins und URLs.
- ✓Bereinige das endgültige HTML direkt vor dem HTML-Sink mit einem gepflegten Allowlist-Sanitizer.
- ✓Beschränke Elemente, Attribute und URL-Protokolle auf die benötigten Funktionen.
- ✓Bearbeite oder parse bereinigtes Markup nicht erneut; bereinige nach jeder nötigen Transformation nochmals.
- ✓Teste die genaue Parserkonfiguration und den Rendering-Sink und halte den Sanitizer aktuell.
FAQ
Es entfernt eine Eingabefunktion, garantiert allein aber keine Sicherheit. Prüfe Links, Bilder, Erweiterungen, erzeugtes HTML und den Einbettungskontext; bereinige die Ausgabe für einen HTML-Sink.
Vermeide das. Nachträgliche Änderungen können unsicheres Markup einführen oder Sanitizer-Entscheidungen aufheben. Transformationen zuerst, Bereinigung zuletzt.
Nein. Nutze es für HTML-Fragmente gemäß dem dokumentierten Bedrohungsmodell, halte es aktuell, verwende eine enge Richtlinie und nutze das Ergebnis nicht in JavaScript- oder CSS-Strings wieder.
Quellen
- CommonMark-Spezifikation — Raw HTML
- Marked-Dokumentation — Sicherheitshinweis
- DOMPurify — README und Verwendung
- OWASP — Schutz vor Cross-Site Scripting
- flawopen.com — Cross-Site Scripting