The woes of sanitizing SVGs

Nature of SVG and Risks

  • Commenters stress that SVG is a markup language, not a simple image format; it’s as dangerous as HTML when untrusted.
  • Main hazards: embedded <script>, event-handler attributes, <foreignObject> with HTML, external URLs in attributes/CSS, <image>/feImage, DTD and namespace tricks.
  • Browsers already treat the same SVG differently depending on context: <img> disables scripts/external loads, while inline and <object> can execute them.
  • Because the same file can be used as both “image” and “document,” simply “allow SVG uploads” is risky.

Subset and New-Format Proposals

  • Many suggest supporting only a restricted SVG subset that covers common “paths + fills” use cases.
  • Existing or proposed subsets/formats are mentioned: SVG Tiny, SVG Tiny PS, SVG Native, BIMI profiles, Android’s vector format, TinyVG, and ideas like “SVG-ES” or “SSVG.”
  • Trade‑off: security and simpler tooling vs losing features such as SMIL animation, filters, and drop shadows. Some see that loss as acceptable for wide adoption; others do not.

Real-World Cases and Tooling

  • Scratch’s history illustrates the pitfalls: initial XSS via <script>, then repeated sanitizer bypasses (including regex-based filtering).
  • Scratch inlines SVGs so it can call getBBox() because many input files have bad viewboxes.
  • There are references to SVG sanitization libraries and to the browser HTML Sanitizer API, which allows a limited SVG subset but bans style by default.

Security Mitigations Discussed

  • Strong preference for CSP over ever-more-complex sanitizers: script-src 'none', sandboxing, and applying CSP directly via <meta http-equiv> in documents or iframes.
  • Iframe sandboxing plus strict CSP is seen as robust but underused, partly due to poor docs and integration friction with modern frameworks.
  • Some propose blocking any http(s) URLs in attributes or constraining SVG by headers like Content-Security-Policy and Sec-Fetch-*.

Embedding Modes and API Ideas

  • Frequent wish for a simple, declarative “safe mode”:
    • Attributes like sandbox or exec="false" on <svg>.
    • Type flags (<img type="ssvg">) or special SVG versions/namespaces that guarantee no scripts or external fetches.
  • Others argue that <img src="file.svg"> already provides a mostly-correct safe image behavior, but lacks dynamic styling (e.g., CSS variables) and DOM interactivity.

Broader Reflections

  • Several see SVG’s scripting and HTML-like complexity as “overreach” when most users just want crisp logos.
  • Others note SVG’s origins as a richer, potentially Flash-like interactive medium, which explains (but doesn’t excuse) today’s security headaches.