A sanitizer can inspect one SVG while the browser ends up interpreting two files. That is the interesting part of Gareth Heyes' new research: an allowed resource reference can cross into content that never went through the same checks.
For anyone reviewing SVG uploads, follow the referenced resources, not just the surviving tags.
The second file matters
In Scalable Vector Grief, published 27 October, Heyes reports that Safari can import SVG content from a same-origin GIF through <use>. The GIF containing the payload does not render when opened directly, yet its content can be imported through the SVG reference. The article explicitly says this is not a true SVG/image polyglot.
The reported chain is:
SVG accepted by a sanitizer
→ <use> references another same-origin upload
→ Safari imports fragment-selected content from that file
→ the researcher's imported event handler executesThe report names cloudflare/svg-hush, jams2/py-svg-hush and bgalek/safe-svg for this technique. It does not pin the Safari build, tested package revisions or fix releases, so this is reported test scope—not a current affected-version matrix.
A legitimate feature crosses the boundary
Referencing another file is ordinary SVG functionality. For example:
<svg xmlns="http://www.w3.org/2000/svg">
<use href="/assets/icons.svg#check" />
</svg>MDN's documentation for <use> describes loading nodes from an external SVG file using a path and fragment identifier. It also notes that browsers may refuse cross-origin resources.
That origin restriction does not establish that a same-origin target is trusted. A controlled sprite file and an arbitrary user upload can share an origin while having very different validation histories.
The useful distinction is between approving a reference and approving what that reference imports. Inspecting the first document does not, by itself, demonstrate the second.
What to trace in an upload review
For each surviving <use> reference, record:
- The resolved target: URL, origin and fragment—not merely the filename extension.
- The target's acceptance path: who can upload or replace it, and whether it receives the same validation as the primary SVG.
- The actual interpretation: browser build, rendering context, response headers and effective CSP. Opening the second file alone is not the same test as importing it.
My starting point would be self-contained uploads unless cross-file reuse is a real requirement. If it is required, the design needs an explicit answer about which resources an uploaded document is allowed to import. “It is on our domain” leaves the important bit unanswered.
For applications that genuinely need reusable SVG symbols, where would you put that boundary: reject file references, map them to a fixed trusted sprite set, or isolate uploaded content? Which legitimate workflow makes that choice difficult?
