My colleague, Mike and I while pondering usual work stuff, began to casually discuss the potential of SVGs, especially how cool is that they are mere XML documents represented as an image — enabling them to act as the perfect latent carriers of Cross-Site Scripting (XSS) payloads.
This isn’t novel either — it’s been done many times before, and it’s better than ‘traditional’ XSS attacks which focus purely on injecting malicious scripts within existing HTML pages.
Scalable Vector Graphics (SVGs)
Scalable Vector Graphics (SVGs) are XML documents which represent an image as a set of curves and graphs using mathematical formulae, as opposed to ‘pixels’ made up of binary data in case of bitmaps. This is why SVGs, as opposed to rasterised bitmaps are easily scalable or resizable without any noticeable loss (pixelation) in the ‘quality’ of the graphic.
SVGs are ideal when designing logos or company branding graphics which could be physically printed on a canvas as small as a business card or as gigantic as a billboard. A well crafted SVG will look virtually the same on any sized medium — small or large. Contrast this with a fixed-size
800 x 800 bitmap image. ‘Stretching’ it on a larger screen would cause pixelation and quality loss.
Creating the payload
In order to craft my XSS payload, I needed an SVG to begin with. I simply converted an existing profile picture, a
.svg using one of the free online converters. Very next moment, my beautiful SVG ‘sketch’ was ready as mere 90 lines of human-readable XML code!
<metadata> but before the
<g> tag, so as not to interfere with the image curves — though in practice it shouldn’t matter really, as long as your XML remains valid. A legitimate use case for including JS within an SVG would have been, for example, to load custom fonts in a logo — but that clearly isn’t our intention here.
XSS Demo followed by their cookie data, and then attempts to redirect the user to a page that will email me their IP address, cookies and other sensitive session data — which could be used to log in to their account as them!
But where should we embed this SVG to carry out the attack? Most websites are smart enough to display SVGs using the
<img> tag, or CSS
background-image property, rendering them useless. These techniques block execution of any scripts present in an SVG as a security measure, as opposed to when
<object> tags are used.
Popular publication Hacker Noon lets users upload their profile avatar using Filestack Picker but perhaps allows a wide-range of MIME types (file types) such as
image/*, as opposed to being more restrictive to a particular type, such as
image/svg+xml file type enabling a hacker to upload an SVG in lieu of a true bitmap image. The attack only seemed to work when using the upload via URL option as opposed to from your device.
The end result
On my profile page and my articles, the profile avatar would load normally, and behave like an image without any script execution taking place — this is because Hacker Noon displays the SVG using a CSS property:
background-image which will not execute the scripts, as explained above.
However, when accessed directly via its static link
https://hackernoon.com/avatars/oTiYTYuLerOJsmYRVttqIdGESsa2.png, the JS would execute successfully (video below).
Don’t be mistaken by the
.png file extension in the link. The uploader used by Hacker Noon merely renamed the extension without actually converting the
.svg to a rasterised image. When the user would access the link directly, the SVG would show its true colours by executing JS, as promised:
And recall that the code we injected within the SVG was designed to further email sensitive information about the victim including cookies, IP address and session data to the hacker:
This is a successful demonstration of how stored Cross-Site Scripting (XSS) attacks can be carried out using SVGs. There are multiple ways a Hacker Noon user could have been tempted to click on the avatar’s static link, such as within the Hacker Noon Community discussion channels or in the “Writer Ad” space. Doing so would’ve emailed their sensitive data to the hacker.
Luckily, within two weeks of its reporting, the vulnerability was resolved and the uploader no longer allows tainted SVGs to be used as profile avatars.
Additionally, according to Filestack engineer Urszula Grudzień, the vulnerability does not impact Filestack Picker itself, therefore in my opinion, it was likely the case of a MIME type misconfiguration on Hacker Noon’s end:
Our engineers have verified your report and we can ensure you, that if the Filestack application does the SVG file [upload, it is] blocked [on] backend side, upload [of] this file type should be not possible, even by using the URL as a source of the file in our Picker.