SVG File Upload Vulnerabilities and Security Risks

Allowing users to upload Scalable Vector Graphics (SVG) without strict sanitization exposes web applications to severe vulnerabilities, most notably Stored Cross-Site Scripting (XSS), XML-based exploits, and account takeover. Because SVGs are XML-based documents rather than simple raster images, browsers treat them as active code capable of executing inline scripts and manipulating the Document Object Model (DOM). This guide breaks down the critical security risks associated with unsanitized SVG uploads and how attackers exploit these mechanisms.

Stored Cross-Site Scripting (XSS)

The primary risk of unsanitized SVG uploads is Stored Cross-Site Scripting. An SVG file can contain native HTML and XML tags such as <script>, embedded <foreignObject> elements, or event handlers like onload, onerror, and onclick.

When an application stores the file and renders it directly inline or serves it via a direct browser link with an image/svg+xml MIME type, the browser executes the embedded JavaScript within the origin of the hosting domain. Because the payload resides on the server, every user who views the image triggers the malicious payload automatically.

Session Hijacking and Account Takeover

Once an embedded script executes via an SVG payload, it runs within the context of the victim's session. Attackers can access sensitive data, such as:

  • Session tokens stored in localStorage or sessionStorage.
  • Non-HttpOnly authentication cookies via document.cookie.
  • CSRF tokens embedded within the application interface.

With these credentials, an attacker can hijack active sessions, impersonate regular users, or compromise administrative accounts, leading to full application takeover.

XML External Entity (XXE) Injection

Because SVGs are structured as XML documents, they are susceptible to XML External Entity (XXE) attacks if the server parses the file during processing, thumbnail generation, or metadata extraction.

If the server-side XML parser is misconfigured to resolve external entities, an attacker can embed malicious entity definitions inside the SVG:

  • Local File Disclosure: Reading sensitive configuration files (such as /etc/passwd or environment variables) from the host server.
  • Server-Side Request Forgery (SSRF): Forcing the host server to make unauthorized requests to internal network services, cloud metadata endpoints, or adjacent private infrastructure.
  • Denial of Service (Billion Laughs Attack): Triggering recursive entity expansion to exhaust server memory and CPU resources.

Phishing and Client-Side Defacement

SVGs can contain interactive elements like standard anchor tags (<a xlink:href="...">) and styling directives. Attackers can craft visually convincing SVGs that mimic standard login forms, warning banners, or interface components. When users interact with the image, they can be redirected to external credential-harvesting pages or presented with deceptive overlays within the trusted context of the primary domain.

Cross-Origin Data Theft

If an SVG executes JavaScript within the domain origin, the script can perform authenticated asynchronous requests (via fetch or XMLHttpRequest) to internal application APIs. The attacker can capture the responses and exfiltrate private user profile data, financial details, or internal communications back to an external command-and-control server.

Essential Mitigation Strategies

To eliminate risks associated with SVG uploads, implement the following defenses:

  • Strict Sanitization: Process incoming SVGs with dedicated XML sanitizers like DOMPurify (configured for SVG) to strip all <script>, <foreignObject>, external entities, and event attributes.
  • Serve from an Isolated Domain: Host user-uploaded SVGs on a separate, sandboxed domain or CDN (e.g., usercontent.example.com) without access to main session cookies.
  • Force Download or Static Rendering: Deliver files with the Content-Disposition: attachment header to force downloads instead of inline execution, or embed SVGs exclusively using the HTML <img> tag, which disables JavaScript execution by default.
  • Enforce Content Security Policy (CSP): Apply a strict CSP header (such as script-src 'none') specifically to endpoints serving raw SVG content.
  • Raster Conversion: Convert uploaded SVGs to raster formats like PNG or WebP on the server before storage and display.