Security

SVG Security: Preventing XSS & Injection Attacks

How to safely handle user-supplied SVG, prevent cross-site scripting via SVG vectors, and sanitize pattern inputs.

10 min read Jan 2026 3 PDF downloads

Why SVG Is a Security Risk

SVG is XML — and XML can contain scripts, event handlers, external references, and XSLT. A malicious SVG file can embed <script> tags that execute when the SVG is rendered as an HTML image, trigger HTTP requests to external servers, load external resources via <image href>, execute JavaScript via event handlers (onload, onclick), and exploit XSLT processing instructions.

Safe vs Unsafe SVG Usage

Safe: SVG as CSS background-image data URI — the SVG is rendered in a sandboxed context; scripts and external references do not execute. SVG referenced via <img src> — also sandboxed. Unsafe: SVG rendered as inline HTML (direct DOM injection) — scripts execute in the page context. SVG in <iframe src> without sandboxing — may execute scripts depending on CSP.

Sanitizing User-Supplied SVG

Never render user-supplied SVG as inline HTML without sanitization. Use DOMPurify (JavaScript) or SVG Sanitizer (PHP/Python). These libraries whitelist safe elements and attributes, stripping anything potentially dangerous. Configure DOMPurify with the SVG profile: DOMPurify.sanitize(svg, { USE_PROFILES: { svg: true, svgFilters: true } }).

// JavaScript: Always sanitize before injecting inline SVG
import DOMPurify from 'dompurify';

const userSvg = getUserInput(); // untrusted
const clean = DOMPurify.sanitize(userSvg, {
  USE_PROFILES: { svg: true, svgFilters: true },
  FORBID_TAGS: ['script', 'use'],
  FORBID_ATTR: ['href', 'xlink:href', 'onload', 'onclick'],
});

// Only then inject:
element.innerHTML = clean;

Content Security Policy for SVG

Implement a strict CSP that blocks inline script execution: Content-Security-Policy: script-src 'self'; object-src 'none'; base-uri 'none'. For SVG data URIs in CSS, allow img-src data:. Restrict default-src to prevent SVG images from loading external resources. Test your CSP with the Google CSP Evaluator.

Validating Pattern Inputs

If you allow users to customise pattern parameters (colours, sizes), validate all inputs server-side. Colour values must match /^#[0-9a-fA-F]{3,6}$/. Numeric values must be within documented ranges. Never interpolate user input directly into SVG templates without validation — a malicious user could inject SVG markup through a colour input field.

The SVG SSRF Risk

Server-Side Request Forgery (SSRF) via SVG: if your server processes uploaded SVG files (e.g., to generate thumbnails), a malicious SVG can reference internal services via <image href="http://169.254.169.254/latest/meta-data/"> (AWS metadata endpoint). Always process SVG files in a sandboxed environment (containerized, no network access) and strip all external references before processing.

Secure Pattern Generation Pipeline

Build SVG patterns programmatically from whitelisted components — never via string interpolation of user input. Accept only primitive values (colour hex, numeric scale, pattern type identifier), validate each input individually, build the SVG using a templating system with proper escaping, and base64-encode the result. User input should never reach the SVG markup level directly.