Walker
Walker

Reputation: 134643

Are user-uploaded .svg's a XSS risk? How can you "sterilize" an SVG?

We have a website that allows users to design graphics, and one of the things we support is SVGs. We want to allow users to upload SVGs, but are concerned with the potential for abuse (including code in the .SVG file).

Is there a way to sterilize .svg files?

Upvotes: 4

Views: 2044

Answers (3)

Luc
Luc

Reputation: 6026

Yes, user-uploaded SVG files can include JavaScript. These execute if you load that image directly (top-level navigation). Someone could be sent a link to check out a funny meme on your website, and unwittingly be running scripts in your website's context in the background.

Modern browsers do not execute scripts inside of <img> tags, so <img src='/uploads/4bafa902.svg'> is safe. However, sending someone a link to https://example.com/uploads/4bafa902.svg will execute scripts if they click it and an iframe would also be unsafe. Imagine a Discord user would get a link leading to discord.com/.../some-image.svg. They probably think it safe to click.

Even if your session ID cookie has HttpOnly set and cannot be accessed by the script, and even with SameSite in use, the browser will still attach it to any requests performed on the expected origin. Because the SVG is hosted on your own website, you will be meeting the origin policy. That scripted SVG can do any action that the user's session can do (e.g., sending and retrieving private messages) and send any obtained data to the attacker's server.

To safely host SVG images, you need to either:

  • Have a Content-Security-Policy (CSP) response header set on SVG images which denies running those scripts. This is the one I use:
    Content-Security-Policy: script-src 'none'; object-src 'none'; report-uri /cspreport
    
  • Remove/sanitize the executable contents from an untrusted SVG, either before hosting it or before serving the contents to users.

Both options have caveats:

The CSP header is often configured globally on the web server. If you set a custom one for SVG content responses, that might be overridden by the web server (probably replaced, or perhaps both are set in a random order).

The cleaning/sanitizing is prone to oversights, and you also need to keep up with new (and perhaps obscure) browser features, similar to how ontouchstart was defined for touchscreen devices only in 2013, nearly twenty years after onclick was defined (maybe VR/AR headsets will get their own events for looking at an element, or an event used by accessibility aids that you're not aware of, or something else we do not have yet today). Thus, I would not try to build my own, but rather trust to a project that focuses on cleaning SVGs against XSS such as DOMPurifier and have a mechanism for keeping them up-to-date.

Having both defences probably gets you the best of both worlds: if the purifier is circumvented, the CSP should still prevent execution, and vice versa.

Upvotes: 3

Robert Longson
Robert Longson

Reputation: 124179

If you display the uploaded svg data as images i.e. <img src="uploadedFile.svg"> in html then UAs won't run any scripts.

Upvotes: 2

Erik Dahlstr&#246;m
Erik Dahlstr&#246;m

Reputation: 60996

Allowing svg upload is similar to allowing html upload, so you will need a similar level of checking the files. See e.g the html5lib sanitizer.

Upvotes: 2

Related Questions