Security Risks of Uploading Untrusted SVG Files
Scalable Vector Graphics (SVG) files are XML-based image formats that allow for dynamic, interactive, and scalable visuals on the web. However, because SVGs are structured as executable XML documents rather than flat binary data, accepting untrusted user uploads introduces severe vulnerabilities. Without rigorous validation and sanitization, uploading malicious SVG files can expose web applications to Cross-Site Scripting (XSS), XML External Entity (XXE) injection, Server-Side Request Forgery (SSRF), Denial of Service (DoS), and HTML injection.
Stored Cross-Site Scripting (XSS)
The most prevalent client-side risk of SVG uploads is Cross-Site Scripting. Because SVGs support embedded JavaScript, attackers can inject malicious scripts directly into the image markup.
Common execution methods include: * Script Elements:
Direct inclusion of <script> tags within the XML
structure. * Inline Event Handlers: Attributes like
onload, onclick, or onerror
attached to vector elements (e.g.,
<svg onload="alert(document.cookie)">). *
Embedded Links: Malicious URLs using the
javascript: pseudo-protocol inside
<a xlink:href="javascript:..."> tags.
When a browser renders an SVG directly from a trusted domain, the embedded JavaScript executes in the context of the user’s session, enabling session hijacking, credential theft, and unauthorized actions.
XML External Entity (XXE) Injection
If an SVG file is parsed or processed on the server (such as generating thumbnails, rasterizing, or extracting metadata), an outdated or misconfigured XML parser can be exploited via XXE injection.
Attackers define external entities in the XML Document Type
Definition (DTD): * Local File Disclosure: Directing
the parser to read local system files (e.g.,
file:///etc/passwd) and return the contents in the rendered
output or error logs. * Internal Network Scanning:
Forcing the server to make network calls to internal IP addresses.
Server-Side Request Forgery (SSRF)
SVGs allow references to external resources through tags such as
<image>, <use>, or
xlink:href. When a server-side rendering library (such as
ImageMagick, Cairo, or Chromium headless) processes the SVG to convert
it to PNG or JPEG, the server automatically fetches these remote assets.
Attackers can leverage this behavior to bypass firewalls, target
internal microservices, or query cloud metadata endpoints (e.g.,
http://169.254.169.254).
Denial of Service (DoS)
Malicious SVGs can target system availability on both the client and server: * Billion Laughs Attack: Nested and recursive XML entity definitions that expand exponentially when parsed, exhausting server memory and CPU. * Quadratic Blowup Attack: Large payloads consisting of repeated entity definitions designed to bypass standard parser limits. * Complex Vector Complexity: Excessively complex paths and deeply nested elements that crash or freeze browser rendering engines.
HTML and Foreign Object Injection
The SVG specification includes the <foreignObject>
tag, which allows arbitrary HTML and XML namespaces to be embedded
directly within an SVG document. Attackers can use this to render
phishing forms, iframes pointing to malicious websites, or spoof
interface elements while maintaining the visual appearance of a
legitimate application graphic.
Essential Mitigation Strategies
To secure web applications against untrusted SVG uploads:
- Sanitization: Use dedicated SVG sanitization
libraries (such as DOMPurify) to strip
<script>,<foreignObject>, event handlers, and remote URLs before saving or displaying files. - Disable DTDs: Ensure all server-side XML parsers strictly disable Document Type Definitions (DTDs) and external entity resolution.
- Serve as Attachments: Set the
Content-Disposition: attachmentHTTP header when serving user-uploaded SVGs directly to prevent browsers from rendering them inline. - Server-Side Rasterization: Convert uploaded SVGs to secure binary formats (such as PNG or WebP) in an isolated, sandboxed environment before storing or serving them.
- Content Security Policy (CSP): Apply a strict CSP
header that disables inline scripts (
script-src 'self') to limit damage if an SVG is executed in the browser context.