9

SVG files are susceptible to billion laughs attack. Our website allows users to upload/submit markdown files and we run the .md file through marked.js before rendering it. Now images in the markdown get rendered as,

<img src="https://evilsite.com/badsvg.svg"/>

in the webpage. Browsers will prevent any <script> in badsvg.svg from executing.

Now evilsite.com can serve badsvg.svg that contains billion laughs payload. This is how different browsers handle it,

Edge/IE - Not impacted as it has a limit on entity expansion (you can see it in the logs in console)

Firefox - Also seems to have a limit on entity expansion

Chrome - No limits, it tries to expand all entities and eventually run out of memory and there's no option but to close/kill the tab

This related bug on Chrome was marked 'wont fix' - https://bugs.chromium.org/p/chromium/issues/detail?id=617891

This is client side DOS and the site basically becomes unusable for any user on Chrome. How do you suggest we prevent this type of attack? Disallowing users from referencing resources from external domains seems an extreme measure.

7
  • 2
    As I see it, disallowing external resources is the correct approach here.
    – Arminius
    Jun 11, 2017 at 18:55
  • @Arminius That's a pretty big thing to disallow. Many sites including Stack Exchange already allow this. Jun 11, 2017 at 19:02
  • @AlexanderO'Mara Stackexchange allows external references? I always though it only permits uploads (or implicit uploads through reference).
    – Arminius
    Jun 11, 2017 at 19:03
  • I left a comment pointing out that the suggestion to sanitize user input doesn't cover externally hosted image. I guess we will see what they say. Jun 11, 2017 at 19:04
  • 1
    Looks like "billion laughs" isn't the only way to exhaust resources, a well formed SVG can eat up memory too (developer.mozilla.org/en-US/docs/Web/SVG/Element/defs) Jun 12, 2017 at 2:14

1 Answer 1

1

As a workaround you could implement something like a SVG proxy on your server which rejects SVG files which trigger the dos and link all SVG files through the proxy e.g. /svgproxy?f=https://evilsite.com/badsvg.svg. But of course there would be a performance disadvantage even if that could be limited by doing the check only for chrome users.

A not too costly way to detect a bad SVG is to try to render the SVG with a process which has a memory limit. If the rendering fails its a bad SVG. You could try ImageMagick which at least sometimes also rejects bad SVGs by itself.

3
  • Yes, GitHub does something similar where they serve any 'images' that you put in the markdown from their own content servers (even if the image is externally hosted). But trying to prevent a client-side DOS attack is more tricky than it seems because a well formed SVG can trigger it too, see updates on bugs.chromium.org/p/chromium/issues/detail?id=617891. Some of the other approaches I've come across suggest to try to render the image on a separate machine (VM or something), and monitor the machine.. way too costly to implement :) Jul 25, 2017 at 2:51
  • i have updated the answer to provide information about how to detect a bad SVG
    – 40F4
    Jul 25, 2017 at 7:32
  • 1
    Using ImageMagick to help with security is irony in it's purest form.
    – user81147
    Jul 25, 2017 at 7:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .