markdown-sanitization-chainlisted
Install: claude install-skill fabioc-aloha/Alex_ACT_Edition
# Markdown Sanitization Chain
> Battle-tested via production XSS incident. The order of markdown → sanitize → diagram render is non-negotiable when content comes from users.
## When to Use
- An app renders markdown supplied by users (comments, docs UI, embedded editors)
- You're about to call `innerHTML` with markdown-derived HTML
- Mermaid or another diagram renderer runs in the browser
- Security review on a markdown-rendering surface
## Why It Matters
Markdown renderers (marked.js, markdown-it) convert markdown to HTML but **do not sanitize it**. Diagram renderers (Mermaid, PlantUML) execute after sanitizers run, which can re-introduce attack vectors. Order matters critically.
## The Rule
**Always: marked.js → DOMPurify → Mermaid (post-render).**
```text
1. Parse markdown to HTML (marked.js)
2. Sanitize HTML (DOMPurify)
3. Insert sanitized HTML into DOM
4. Render diagrams on the now-sanitized DOM (Mermaid.run())
```
Never skip the sanitizer even if content is "trusted." Trust gets revoked when the threat model changes; the chain stays.
## Implementation
```javascript
import { marked } from 'marked';
import DOMPurify from 'dompurify';
import mermaid from 'mermaid';
async function renderMarkdown(content, container) {
// Step 1: parse markdown to HTML
const rawHtml = marked.parse(content);
// Step 2: sanitize BEFORE inserting into the DOM
const cleanHtml = DOMPurify.sanitize(rawHtml, {
ADD_TAGS: ['mermaid'], // allow mermaid tag