dev / notes

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 img tag.

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.

An astute reader will notice the hash doesn’t match anymore. That’s because I felt compelled it show the browser bar but also match this page’s background color with Glimpse after. So, TL;DR: I’m anal and you can’t do self-referential hashing…Javascript popup that says: GOT YA!

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,

https://p.falsifiable.page/:contentHash

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.