Files
stack/docs/scratchpads/200-mermaid-xss-enhancement.md
Jason Woltje f87a28ac55
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix(#200): Enhance Mermaid XSS protection with DOMPurify
Added defense-in-depth security layers for Mermaid rendering:

DOMPurify SVG Sanitization:
- Sanitize SVG output after mermaid.render()
- Remove script tags, iframes, objects, embeds
- Remove event handlers (onerror, onclick, onload, etc.)
- Use SVG profile for allowed elements

Label Sanitization:
- Added sanitizeMermaidLabel() function
- Remove HTML tags from all labels
- Remove dangerous protocols (javascript:, data:, vbscript:)
- Remove control characters
- Escape Mermaid special characters
- Truncate to 200 chars for DoS prevention
- Applied to all node labels in diagrams

Comprehensive XSS Testing:
- 15 test cases covering all attack vectors
- Script tag injection variants
- Event handler injection
- JavaScript/data URL injection
- SVG with embedded scripts
- HTML entity bypass attempts
- All tests passing

Files modified:
- apps/web/src/components/mindmap/MermaidViewer.tsx
- apps/web/src/components/mindmap/hooks/useGraphData.ts
- apps/web/src/components/mindmap/MermaidViewer.test.tsx (new)

Fixes #200

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 22:55:57 -06:00

2.4 KiB

Issue #200: Enhance Mermaid XSS protection with DOMPurify

Objective

Add defense-in-depth security layers to Mermaid rendering:

  1. DOMPurify SVG sanitization
  2. Input sanitization for labels
  3. Comprehensive XSS attack testing

Current State

  • Core XSS protection already in place (strict mode, htmlLabels: false)
  • Issue #190 fixed critical vulnerability
  • Need to add additional security layers for defense-in-depth

Approach

  1. Check if DOMPurify is installed, install if needed
  2. Add DOMPurify SVG sanitization in MermaidViewer
  3. Add sanitizeMermaidLabel() function in useGraphData
  4. Write comprehensive XSS tests (TDD)
  5. Verify all attack vectors are blocked

Implementation Plan

  • Create scratchpad
  • Check/install DOMPurify (already installed)
  • Write XSS attack tests (TDD - RED)
  • Add DOMPurify to MermaidViewer
  • Add label sanitization to useGraphData
  • Run tests (GREEN) - 15/15 tests passing
  • Verify type checking passing
  • Commit and close issue

Changes Made

MermaidViewer.tsx

  • Imported DOMPurify
  • Added SVG sanitization with DOMPurify after mermaid.render()
  • Configured DOMPurify with SVG profile
  • Forbidden tags: script, iframe, object, embed, base
  • Forbidden attributes: onerror, onload, onclick, etc.

useGraphData.ts

  • Added sanitizeMermaidLabel() function
  • Removes HTML tags
  • Removes dangerous protocols (javascript:, data:, vbscript:)
  • Removes control characters
  • Escapes Mermaid special characters
  • Truncates to 200 chars for DoS prevention
  • Applied to all labels in mindmap and flowchart generation

MermaidViewer.test.tsx (new)

  • 15 comprehensive XSS tests
  • Tests script tag injection
  • Tests event handler injection (onerror, onclick, onload)
  • Tests JavaScript URL injection
  • Tests data URL injection
  • Tests SVG with embedded scripts
  • Tests HTML entity bypass attempts
  • Tests DOMPurify integration
  • Tests safe content rendering

All 15 tests passing!

Test Cases

  1. Script tags in labels: <script>alert(1)</script>
  2. Event handlers: <img src=x onerror=alert(1)>
  3. JavaScript URLs: javascript:alert(1)
  4. Data URLs: data:text/html,<script>alert(1)</script>
  5. SVG with embedded scripts
  6. HTML entities bypass attempts

Files to Modify

  • apps/web/src/components/mindmap/MermaidViewer.tsx
  • apps/web/src/components/mindmap/hooks/useGraphData.ts
  • apps/web/src/components/mindmap/MermaidViewer.test.tsx (new)