October 28, 2026
Six SVG sanitizers failed Gareth Heyes’s browser tests
Yesterday, PortSwigger researcher Gareth Heyes published a useful stress test for SVG uploads: eight popular sanitizers examined, six…
By Saroyan Zorayr
1 min read
Yesterday, PortSwigger researcher Gareth Heyes published a useful stress test for SVG uploads: eight popular sanitizers examined, six bypassed. The interesting result is not a league table. It is how much browser behavior sits outside the markup a sanitizer checks.
SVG is an XML document that browsers can render as an image. It also supports links, namespaces, animation, and references to other resources. A sanitizer can remove dangerous-looking elements and still miss the way a browser interprets the delivered file.
Three places the boundary moved
One library rendered the SVG before searching for a forbidden element. The browser normalized foreignObject, while the library's lowercase selector missed it. That is a parser and DOM mismatch, not a missing blacklist entry.
A second route used XSLT. Heyes showed that Firefox could apply a stylesheet supplied through a Link response header to an otherwise harmless XML body. The executable behavior came from the response context. Reviewing only the body would miss it.
In Safari, a same-origin <use> reference could pull SVG content from an uploaded GIF. The sanitized SVG looked simple; the referenced resource changed what the browser processed. This route depends on the browser and on how uploads are served.
Heyes reports that DOMPurify and darylldoyle/svg-sanitizer resisted the techniques in his post. That is a result for these tests, not a guarantee for every deployment. The six-of-eight figure is a researcher-selected sample, not a measured failure rate for the whole ecosystem.
What I would test in an upload pipeline
Start with the actual response. Record the sanitized bytes, content type, content disposition, CSP, origin, and any same-origin files the SVG can reference. Then open that delivered artifact in the browsers your users support. A unit test that stops at sanitizer output never reaches the behavior shown in this research.
Keep upload content on a separate origin where possible, use restrictive response policy as another layer, and verify that references and transformations behave as expected. For each sanitizer dependency, track upstream advisories and fixed releases. The article does not provide one patch matrix that covers every affected project.
I have not reproduced these cases against current application deployments. The value of the new work is a test design: compare what the sanitizer approved with what each browser actually executed, under the same headers and origin rules as production.
Primary source: Gareth Heyes, "Scalable Vector Grief," PortSwigger Research, 27 October 2026.