Security Risks of Rendering Inline SVGs
Rendering user-submitted Scalable Vector Graphics (SVG) directly as inline markup introduces severe security vulnerabilities to web applications, most notably Cross-Site Scripting (XSS). Because SVG is an XML-based vector image format that supports embedded executable code, rendering untrusted SVGs within the main Document Object Model (DOM) grants attacker-controlled code full access to the application’s origin. Understanding the mechanisms of these risks—including script execution, DOM manipulation, and data exfiltration—is essential for implementing effective defenses.
Cross-Site Scripting (XSS)
The most critical danger of inline SVGs is Cross-Site Scripting. Unlike raster formats (such as PNG or JPEG), the SVG standard permits interactive features, which include JavaScript execution. When an SVG is inlined directly into HTML:
<script>Tags: Attackers can embed standard JavaScript tags inside the SVG. When the browser renders the inline SVG, it executes the script immediately in the context of the host application.- Inline Event Handlers: Attributes like
onload,onerror,onmouseover, oronclickcan be attached to any SVG element (e.g.,<svg onload="alert(document.domain)">or<rect onmouseover="...">), triggering malicious code upon rendering or user interaction. - Hyperlinks and
javascript:URIs: SVGs support the<a>tag andxlink:hrefattributes, allowing attackers to construct links that execute JavaScript when clicked.
Because the code runs in the host page’s origin, the attacker can steal session cookies, capture user input, perform unauthorized API requests, and hijack user accounts.
DOM Cloaking and Page Hijacking
When an SVG is injected as inline HTML, all of its internal nodes become part of the parent page’s DOM tree. This introduces unique structural risks:
- DOM Cloaking: Attackers can craft SVG elements with
specific
idornameattributes to overwrite global JavaScript variables or properties (e.g.,<a id="config" href="...">), leading to unintended logic bypasses in existing client-side scripts. - CSS Injection and Phishing: Embedded
<style>blocks inside the SVG can alter the styles of the entire hosting web page. An attacker can hide legitimate UI elements, alter forms to redirect credentials to a third-party server, or overlay deceptive phishing interfaces.
External Resource Loading and Exfiltration
SVGs can reference external resources using elements such as
<image>, <use>, and
<feImage>. In an inline rendering context, this
enables:
- User Tracking and Exfiltration: Embedded styles and resource tags can trigger outbound HTTP requests containing sensitive tokens via CSS attribute selectors.
- Cross-Origin Leaks: Referencing external SVG sprites or assets across domains can lead to information disclosure depending on browser security boundaries and CORS configurations.
XML Parsing Vulnerabilities
Before an SVG reaches the DOM, it is often processed by server-side or client-side XML parsers. Untrusted SVGs can exploit weak parser configurations:
- XML Entity Expansion (Billion Laughs Attack): Nested entity declarations can exhaust server or browser memory, resulting in Denial of Service (DoS).
- XML External Entity (XXE) Injection: If parsed server-side with insecure XML libraries, an SVG can be used to read local files, scan internal networks, or execute remote requests.
Safe Alternatives to Inline Rendering
To eliminate the security risks of user-submitted SVGs, use one of the following approaches:
- Serve as Static Images: Load the SVG via an
<img>tag (e.g.,<img src="user-graphic.svg">) or as a CSSbackground-image. Browsers automatically disable JavaScript execution and interactive features for SVGs loaded in an image context. - Isolate on a Separate Domain: Host user-uploaded files on a completely separate, sandboxed domain (e.g., a dedicated asset or CDN domain) with no access to sensitive cookies or session storage.
- Strict Sanitization: If inlining is required, pass
the SVG through a dedicated, actively maintained sanitizer (such as
DOMPurify) configured specifically to strip
<script>tags, event handlers, foreign namespaces, and untrusted XML entities. - Implement a Content Security Policy (CSP): Restrict
script execution contexts with a restrictive
script-srcandobject-srcpolicy to prevent unauthorized inline script evaluation.