A battery of test cases designed to test how browsers handle CSS, JavaScript, and external objects loaded from SVG documents.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


SVG Security Test Suite 

This project contains a battery of test cases designed to test how browsers 
handle CSS, JavaScript, and external objects loaded from SVG documents.

To run the tests, serve the directory `svg.test` from an Apache+PHP web server 
using the configuration given in `svg.test.conf`. Point all of the server 
names and aliases in `svg.test.conf` at the web server, then load 
http://svg.test using the browser that you want to test.  Pick a page from the 
test matrix and compare the actual results against the listed expected results.

Each page loads SVGs from different sources under different X-Frame-Options 
(XFO) and Content-Security-Policy (CSP) settings.  Pages contain several 
related test cases, and each test case is a row of SVGs loaded in eight 
different ways.  The base of each test case is a gray SVG circle.  Some test 
cases attempt to apply a stylesheet (either in-line in the SVG or external), 
which changes the colour of the SVG to orange.  Some test cases attempt to run 
a script (again, either in-line or external) which adds a red border to the SVG 
and attempts to call a function on the parent document that changes the border 
from solid to dashed.  Embedded image cases attempt to load a second image from 
within a gray circle SVG (scaled to 50%, in the bottom-right corner), with 
scripts and styles applied to the child.  Recursion test cases attempt to load 
a single SVG recursively.

Some test cases will intentionally fail to load because they aren't meaningful, 
such as in-line and data URI images in the different-origin pages.  Others 
should fail to load in certain cases due to the security policies applied to 
the page.  In many cases, only part of an image will load, such as the gray 
circle loading but its styesheet not being applied or its child images not 
loading.  Compare the images as rendered in your browser to the expected 
results listed below the images.

There may be errors in the expected results.  If you find one, please point it 
out and explain why it is incorrect.  Ideally, back up your arguments with 
relevant standards.

Note that in-line SVG is not considered to be an image from the perspective of 
CSP (rather than being considered logically similar to an object tag with a 
data: URI).  Consequently, it is unaffected by CSP.  See this thread on 
WebAppSec: http://lists.w3.org/Archives/Public/public-webappsec/2014Jul/0113.html

This project may be modified or redistributed under the terms of the GNU GPL, 
version 2.  See LICENCE for details.

Last Tested

**Firefox**: 36.0a2 aurora  
**Chrome**: 41.0.2241.0 canary  
**Internet Explorer**: 11.0.9879.0 (Windows 10 Technical Preview) 

Known security model violations

*   Internet Explorer always loads and applies external CSS on static images, 
    regardless of its origin (though CSP blocks them correctly in the 
    11.0.9879.0 technical preview build).  This issue was reported to Microsoft 
    in summer 2014.

*   Old Chrome builds always loaded and applied external CSS on static images 
    (unless banned by CSP), but only if the CSS came from a different origin 
    than the image.  This was fixed in build 37.0.2054.0 and was picked up by 
    Apple in [CVE-2014-4465](http://support.apple.com/en-us/HT6596).  [Bug 
*   Internet Explorer always loads external images, even from a static image 
    context (though CSP blocks them correctly in the 11.0.9879.0 technical 
    preview build).  It never loads a document as a child of itself, but as 
    long as the URI changes at every iteration, SVGs loaded as static images 
    can be nested to an arbitrary depth.  Scripts don't run in static images, 
    so a deeply nested SVG requires a server-side script or a very large number 
    of images stored on the server.  Using bug-repros/recurse.svg.test/recursive-image.js 
    (a Node.js script) to serve identical SVGs with different names, IE 11 will 
    load it a few hundred thousand times until it runs out of memory and 
    crashes.  This issue was reported to Microsoft in summer 2014; they 
    dismissed it as "not a security bug".

*   Chrome applies in-line CSS to static images in violation of CSP.  [Bug 
*   Prior to version 28.0, Firefox did not apply CSP to sandboxed iframes. 
    This appears to have been due to wider problems with sandboxed iframes.

Known stability and functionality issues

*   Chrome and Internet Explorer both crash when loading a recursive SVG that 
    loads itself using a `html:object` tag inside an `svg:foreignObject` tag, 
    with a script that appends a counter as a query parameter to the nested 
    SVG's URI so that every iteration's URI is unique.  Internet Explorer 11 is 
    documented as [not supporting](http://msdn.microsoft.com/en-us/library/hh834675(v=vs.85).aspx)
    `svg:foreignObject` and it indeed does not render `foreignObject` contents, 
    but it does run scripts and load external documents from within 
    `foreignObject`, which is all that is necessary for this attack.  A [Chrome 
    bug](https://code.google.com/p/chromium/issues/detail?id=383180) is open.  
    Microsoft dismissed my bug report as "not a security bug".  Both browsers 
    should take a lesson from Firefox on this one, which is to stop loading 
    nested documents at 10 levels.  There is a proof of concept script in 
*   Chrome applies both CSP `object-src` and `frame-source` to nested browsing 
    contexts created from `object` and `embed` tags, rather than only 
    `object-src`.  `frame-src` is only supposed to apply to `frame` and 
    `iframe` tags, though I'm not sure why the designers of CSP felt that 
    frames needed to be handled differently than objects and embeds.  [This 
    WebAppSec thread](http://lists.w3.org/Archives/Public/public-webappsec/2014Aug/0049.html)
    discusses the issue.  [Bug tracker](https://code.google.com/p/chromium/issues/detail?id=400840).

*   Chrome doesn't handle CSP 'self' correctly to sandboxed iframes.  If a 
    document in a sandboxed iframe tries to load an external stylesheet from 
    the same source, it will be blocked by CSP unless the source is explicitly 
    listed in `style-src`; Chrome blocks it even under `style-src 'self';`.  
    Similarly, attempts by a sandboxed iframe to load an image from the same 
    source with a CSP that permits `img-src 'self'` will be blocked.  I haven't 
    tested other CSP directives, but expect that the same issue will occur.
    [This WebAppSec thread](http://lists.w3.org/Archives/Public/public-webappsec/2014Dec/0275.html)
    discusses this issue.  [Bug tracker](https://code.google.com/p/chromium/issues/detail?id=443444).

*   Internet Explorer 11.0.9879.0 fails to load SVGs that contain 
    `foreignObject` blocks as static images.  It does load them as nested 
    documents, though it does not render the `foreignObject` contents.

*   Neither Firefox nor Chrome seem to render foreignObjects in in-line SVG. 

*   Chrome doesn't render objects or embeds (though it does render images and 
    iframes) within foreignObjects in sandboxed iframes.  This used to work in 
    old builds such as 27.0.1453.93. (bug-repros/*.chrome-iframe-foreignobject.test)

Future work

*   Mobile browsers
*   HTML and embedded SVG with different CSPs, especially if they're 
*   Multiple contradictory CSPs on a single document, including header and meta 
    tag versions.
*   SVG with in-line `data:` URIs.
*   SVG's `use` element and anything else that takes a URI argument
*   SVG 2.0: <code>iframe</code> and <code>canvas</code> and other stuff
*   CSP 2

Contact information

Rennie deGraaf <rennie.degraaf@gmail.com>

To Do

*   Better documentation for bug-repros/*
*   Re-run the recursive SVG tests on current browsers
*   Submit bug reports
*   Update composed CSP stuff