🧜♂️ fix: Preserve Mermaid foreignObject HTML in Sanitized SVG - #12819
Conversation
bfdd9d6 to
9ddc0ee
Compare
There was a problem hiding this comment.
Pull request overview
Fixes Mermaid inline rendering by updating SVG sanitization so foreignObject HTML survives DOMPurify and the serialized SVG remains valid XML for blob-based <img> rendering (preserving multiline labels and <br />).
Changes:
- Added
sanitizeMermaidSvg()helper that sanitizes with DOMPurify (SVG + HTML profiles) and re-serializes viaXMLSerializer. - Updated
useMermaidto route rendered Mermaid SVG output through the new helper. - Added Jest regression tests covering
foreignObjectpreservation, XML-safe<br />serialization, and XSS stripping.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| client/src/utils/mermaid.ts | Adds a dedicated Mermaid SVG sanitizer that preserves foreignObject HTML and serializes back to XML. |
| client/src/hooks/Mermaid/useMermaid.ts | Replaces inline DOMPurify sanitization with the shared sanitizer helper. |
| client/src/utils/tests/mermaid.test.ts | Adds regression tests to ensure HTML-in-foreignObject survives while unsafe content is removed. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <copilot@github.com>
9ddc0ee to
7e87d9c
Compare
|
@danny-avila ready for review, fresh rebase on dev |
|
@codex review |
|
Codex Review: Didn't find any major issues. 👍 ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
foreignObject HTML in Sanitized SVG
Summary
This change fixes Mermaid inline rendering so sanitized SVGs keep HTML content inside foreignObject, which preserves multi-line labels and
<br />line breaks in the browser while keeping DOMPurify in place. The sanitizer was moved into a dedicated helper in client/src/utils/mermaid.ts, and client/src/hooks/Mermaid/useMermaid.ts now routes rendered SVGs through that helper instead of using the previous inline sanitize call.The new helper uses DOMPurify with SVG, SVG filter, and HTML profiles enabled, allows Mermaid’s required SVG tags and attributes, and returns a DOM fragment that is serialized back to XML so foreignObject HTML survives and
<br />stays XML-safe for blob-based<img>rendering. Regression coverage was added in client/src/utils/tests/mermaid.test.ts for the browser issue we hit: preserving foreignObject children, keeping self-closing<br />, retaining required SVG attributes, and continuing to strip unsafe scripts, event handlers, and javascript: URLs.Change Type
Testing
Example Mermaid Code:
graph LR A[CN Branch CAMs] --> B[Zero Trust Architecture] A --> C[JADC2 Interoperability] A --> D[AI-Ready Infrastructure] A --> E[Cloud-Native Systems] A --> F[Cyber Resilience CDO] A --> G[Rapid Deployment] A --> H[Cost-Effectiveness] A --> I[Warfighter-Centric Design] A --> J[Supply Chain Security] A --> K[Small Business Teaming] B --> L[DoD ZTA Strategy 2.0 March 2026] C --> M[ABMS BAA Open Architecture] D --> N[DoD AI Strategy Jan 2026] E --> O[DAF Network of Future Sep 2025] F --> P[Great Power Competition China/Russia] G --> Q[DevSecOps 2.0 Software Acceleration] H --> R[DoD IT Budget Efficiency Mandate] I --> S[Williams Leadership Vision Dec 2025] J --> T[AFLCMC SCRM Network] K --> U[AFLCMC SBO OTA/BAA/SBIR] style A fill:#e1f5ff style B fill:#fff4e1 style C fill:#fff4e1 style D fill:#fff4e1 style E fill:#fff4e1 style F fill:#fff4e1 style G fill:#fff4e1 style H fill:#fff4e1 style I fill:#fff4e1 style J fill:#fff4e1 style K fill:#fff4e1Before Fix:

After Fix:

Checklist
Please delete any irrelevant options.