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.

  • 2
    As I see it, disallowing external resources is the correct approach here. – Arminius Jun 11 '17 at 18:55
  • @Arminius That's a pretty big thing to disallow. Many sites including Stack Exchange already allow this. – Alexander O'Mara Jun 11 '17 at 19:02
  • @AlexanderO'Mara Stackexchange allows external references? I always though it only permits uploads (or implicit uploads through reference). – Arminius Jun 11 '17 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. – Alexander O'Mara Jun 11 '17 at 19:04
  • @Arminius It's possible if you enter the markdown manually. I think the reason being some images may not be of a compatible license. – Alexander O'Mara Jun 11 '17 at 19:06
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.

  • 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 :) – Techtwaddle Jul 25 '17 at 2:51
  • i have updated the answer to provide information about how to detect a bad SVG – 40F4 Jul 25 '17 at 7:32
  • Using ImageMagick to help with security is irony in it's purest form. – user81147 Jul 25 '17 at 7:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.