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 likeContent-Security-PolicyandSec-Fetch-*.
Embedding Modes and API Ideas
- Frequent wish for a simple, declarative “safe mode”:
- Attributes like
sandboxorexec="false"on<svg>. - Type flags (
<img type="ssvg">) or special SVG versions/namespaces that guarantee no scripts or external fetches.
- Attributes like
- 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.