UGC and SVGs
Reducing the Attack Surface A Bit
In general, SVGs are useful. For scientific work, they’re wonderful. They scale perfectly and don’t weigh to much. But, if embedded, they are also a security nightmare. As this post points out, even wordpress doesn’t have support for them yet. This is unfortunate because embedded SVGs make for really fast page renders. I toyed around with using a few sanitizer modulesIn particular, rnitta/svgsanitizer and mattkrick/sanitize-svg. but failed to find a production-grade solution. Consequently, all SVGs get included via the
src attribute to an
When included via an
img tag, the browser security model inhibits fetching any other resources as well as script executionMDN says the same.. To demonstrate this, consider the following not-so-smiley-face SVG,
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"> <script>//<![CDATA[ alert("GOT YA!"); //]]> </script> <circle cx="50" cy="50" r="40" stroke="black" stroke-width="4" fill="yellow" /> <circle cx="40" cy="35" r="4" stroke="none" fill="black" /> <circle cx="70" cy="35" r="4" stroke="none" fill="black" /> </svg>
You’ll notice there is a
CDATA script that emits a browser alert. You’ll also notice you did not receive an alert. That’s the browser’s security model protecting you. However, if you right-click \(\mapsto\) Open image in new tab, you’re greeted with the alert.
Without care, this presents an obvious problem. If a curious visitor happens open the image in an new tab – accidentally or not – an attacker could use that opportunity to execute an exploit. Techniques like
HttpOnly cookies help mitigate the risk, but it still persists.Even if only because one day, I or someone working for me accidentally pushes an update that removes the flag, bypassing all the unit-tests, somehow. Therefore, for an added degree of protection, all SVG documents are served from,
Why does my SVG look wrong?
This method of inclusion may also cause problems for some documents. For example, if your SVG uses CSS to reference an external font, it won’t get rendered correctly. If you want to verify yours renders correctly, use,
abreka nb preview
prior to publishing.