Skip to content

Sanitize SVG content in the SDK to prevent XSS #7876

@MitjaBezensek

Description

@MitjaBezensek

Problem

SVG files are executable documents, not inert images. When users paste or import SVGs into tldraw, there's no sanitization step — meaning malicious SVGs with embedded scripts, cross-origin references, or phishing links can make it through to rendering.

Attack vectors in the current codebase

  1. SVG text pasting — User-pasted SVG text is parsed via DOMParser and stored as an asset with no sanitization (defaultExternalContentHandlers.ts:314)
  2. SVG file drops — SVG files dropped onto the canvas are handled as image assets without content inspection
  3. Bookmark favicons — Favicon URLs extracted from fetched pages could point to malicious SVGs (BookmarkShapeUtil.tsx:216)
  4. SVG export round-trips — Exported SVGs re-imported could carry injected content

While <img> tags don't execute scripts, SVGs opened as top-level documents or injected via other means can.

Proposed solution

Add SVG sanitization as a defense-in-depth measure in the SDK. One strong candidate is svg-hush from Cloudflare:

  • Allowlist-based approach — removes elements/attributes not explicitly permitted
  • Strips scripting, cross-domain links, and cross-origin resource references
  • Written in Rust (could compile to WASM for browser use)
  • MIT licensed, actively maintained

Where to sanitize

  • In defaultExternalContentHandlers.ts before SVG text is stored as an asset
  • In the asset creation pipeline for SVG files
  • Optionally as a configurable sanitizeSvg hook so SDK users can customize

Alternatives

  • DOMPurify — widely used HTML/SVG sanitizer, pure JS, larger scope than needed
  • Manual strip — remove <script>, event attributes, etc. manually (error-prone, incomplete)
  • CSP headers only — helps but is a dotcom-level mitigation, not an SDK-level one

Considerations

  • Bundle size impact of WASM module vs. JS-only solution
  • Whether sanitization should be opt-in or on-by-default
  • Performance impact on large/complex SVGs
  • Need to preserve valid SVG features (filters, gradients, masks) while stripping dangerous ones

Metadata

Metadata

Assignees

Labels

sdkAffects the tldraw sdk

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions