How Stripping SVG Scripts Secures Uploaded Avatars
Scalable Vector Graphics (SVG) are popular for user avatars due to
their scalability and small file sizes, but they introduce severe
security risks because they are XML-based code capable of executing
JavaScript. Allowing users to upload raw SVG files creates a high-risk
vector for Stored Cross-Site Scripting (XSS) attacks. By sanitizing SVGs
to strip out explicit <script> tags and inline event
attributes, applications neutralize executable code and ensure that
uploaded files function strictly as visual graphics rather than
malicious scripts.
Why SVGs Pose a Security Risk
Unlike raster image formats like JPEG or PNG, an SVG is an XML document. Modern web browsers parse and render SVGs using the full Document Object Model (DOM). Because SVGs follow standard XML and HTML capabilities, they natively support embedded CSS, external entity references, and client-side scripting.
If an application accepts an unvalidated SVG avatar and renders it inline or allows users to open it directly in the browser, any JavaScript embedded within the file runs inside the victim’s session. This allows an attacker to steal session tokens, manipulate account data, or perform actions on behalf of the user.
Eliminating Direct
Execution via <script> Tags
The most direct way to weaponize an SVG file is by embedding standard
<script> elements:
<svg xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">
fetch('/steal-cookies?data=' + document.cookie);
</script>
</svg>When a sanitization pipeline parses the XML tree and strips all
<script> elements, it eliminates direct, standalone
code blocks. Without these tags, the browser cannot execute traditional
script bodies embedded within the vector data.
Preventing Execution via Event Attributes
Attackers frequently bypass basic script-tag filters by using inline
event handler attributes. In an SVG, almost any visual element can host
event handlers, such as onload, onerror,
onclick, or onmouseover:
<svg xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100" onload="alert(document.domain)" />
</svg>When the browser renders the <rect> element, the
onload attribute executes the JavaScript payload
immediately, without relying on a <script> tag.
Stripping all attributes that match event listener patterns
(typically any attribute starting with on,
case-insensitively) ensures that rendering a shape, path, or gradient
cannot trigger an automated or user-interactive script execution.
Additional Sanitization Vectors
To make SVG avatar uploads entirely secure, stripping scripts and event attributes should be paired with the removal of other execution vectors:
javascript:Pseudo-Protocols: Attackers can place malicious URIs insidehreforxlink:hrefattributes within<a>or<use>tags.- Dangerous Elements: Elements such as
<foreignObject>,<embed>,<object>, and<iframe>can load external HTML or executable content and should be removed. - Safe Display Strategies: Serving user-uploaded SVGs
via standard
<img>tags (which inherently disable JavaScript execution in most modern browsers) or converting uploaded SVGs to raster formats like PNG on the server provides an additional layer of defense.
Sanitizing SVG avatars by removing <script>
elements and event attributes effectively turns an active, executable
XML document into passive visual data, eliminating XSS vulnerabilities
while preserving image fidelity.