Safeguard
Application Security•

ASVS 5.0 V1.3.4: Sanitize User Supplied SVG Files

ASVS V1.3.4 requires SVG uploads to be reduced to safe tags and attributes. Learn why SVG is code, how to sanitize it, and how to test uploads.

Safeguard Security Team
3 min read

ASVS 5.0 V1.3.4 (Level 2) requires that user supplied SVG content is validated or sanitized so it contains only the tags and attributes your application needs for drawing, and no scripts, foreignObject elements or similar active content. SVG is XML that browsers treat as a document, so it can run script.

Why it matters

An avatar upload of evil.svg with an onload attribute or an embedded script element runs JavaScript when someone opens the image URL directly, and it can run under your own origin. That gives an attacker access to sessions and the page's data. SVG can also pull in external resources and entities, which leads to tracking and server side file reads when it is processed on the server.

How to implement it

Pick one of three routes, in order of safety:

  1. Do not accept SVG. Accept PNG or JPEG, and re-encode them.
  2. Rasterize the SVG on upload to PNG in a sandboxed process, and store only the PNG.
  3. Sanitize with an allowlist library, then serve with safe headers.

For route three, DOMPurify can run in SVG mode:

const clean = DOMPurify.sanitize(svgText, {
  USE_PROFILES: { svg: true },
  FORBID_TAGS: ['script', 'foreignObject', 'use', 'animate', 'set'],
  FORBID_ATTR: ['style'],
});

Whatever you choose, also serve user files from a separate domain, with Content-Type: image/svg+xml, X-Content-Type-Options: nosniff and Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; sandbox. Parse server side with an XML parser that has external entities and DTDs disabled.

How to test it

Upload an SVG with onload="alert(1)", one with a script element, one with a foreignObject containing HTML, and one referencing an external image. Open the stored URL directly. No alert may fire and the dangerous elements must be gone from the stored file.

Common mistakes

  • Checking the file extension or MIME type only.
  • Embedding SVG inline in HTML pages without sanitizing.
  • Serving uploads from the main application domain.

Where this goes wrong in practice

Teams usually discover the problem through a profile picture feature. A designer wants vector logos, so SVG is allowed, stored in a bucket and served from the main domain. The file opens as a document, and its script runs with access to cookies and local storage for that domain. Moving uploads to a separate cookieless domain is a high value fix on its own, because even an unsanitized file then has nothing to steal.

Server side processing adds a second risk. Libraries that rasterize SVG may follow external references and entities, so an uploaded file can make your server fetch internal addresses, which links this requirement to SSRF protection. Run conversion in a sandbox without network access, with time and memory limits, and treat conversion failures as rejection rather than retry.

Finally, keep a list of the SVG elements you really need. Most logo and icon use cases need paths, shapes, groups and gradients. Everything else can go.

Quick check

Why can an image file run code?

SVG is an XML document format. Browsers allow script and active elements in it when it is opened as a document.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.