SVG uploads in WordPress (the Inconvenient Truth)

Enabling uploads of SVG files in WordPress is quite easy, and there is a tonne of posts on the Interwebs explaining how you do it. Usually along the lines of:

function add_svg_to_upload_mimes( $upload_mimes ) { 
	$upload_mimes['svg'] = 'image/svg+xml'; 
	$upload_mimes['svgz'] = 'image/svg+xml'; 
	return $upload_mimes; 
} 
add_filter( 'upload_mimes', 'add_svg_to_upload_mimes', 10, 1 );

And that’s pretty much it.

Except it is not.

Why WordPress doesn’t allow uploading SVGs

WordPress is an excellent CMS “out of the box”, very easy to use and “just works” for the large majority of users. So why aren’t SVGs allowed in the first place? Why do we have to jump through hoops to make SVGs work?

Short answer: SVG files are extremely unsecure.

Long answer: SVG support in WordPress have been discussed in trac ticket #24251 for a very long time, and probably will be discussed further for a very long time.

Contrary to what many people believe, SVG is not an image format. It is a document format. Unfortunately for us who just want vector graphics on the web, it is also quite a powerful and flexible document format. As an example, SVG files allows JavaScript to be embedded and SVG readers, i.e. your browser, are expected to execute it.

This is a valid SVG file picturing a red circle:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
<circle cx="50" cy="18.4" r="18.4" fill="#f00" /> 
<script> 
 alert( 'Well, hello there!' ); 
</script> 
</svg>

Notice anything funny with it? Try saving it as a file on your computer and open it in a browser. The result might look something like this:

Browser window showing an alert box with the text “Well, Hello There!”

Looks like we got more than just an innocent image with a red circle. This would be very easy to exploit in a XSS attack.

Q: So why can’t we just run the SVG through a KSES filter that removes the script elements?
A: Because XSS is just the simplest problem. Since SVG is XML based, it opens for a plethora of problems, e.g. XXE, Billion laughs, quadratic blowup etc.

In the above mentioned trac ticked Chris Christoff (chriscct7) explains:

SVG file security isn’t some obscure bug. There’s multiple, well known SVG vulnerabilities. It isn’t a theory, an obscurity, or an unknown. There are well over 8,000 logged CVE’s that have to do with all sorts of fun and obscure SVG file security vulnerabilities.

Further on, Ian Dunn, points out that an SVG sanitizer might not be so easy to write:

Mario Heiderich, one of the researchers who popularized the security issues, tried writing a sanitizer and found it to be harder than even he imagined.

The thing is that “security people who have vast background in web attacks and XSS” have written DOMPurify – “a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG”. It is, however, written in JavaScript for the client side, so it’s probably not something we easily can include in WordPress.

Anyhow, Daryll Doyle (enshrined), used DOMPurify as a basis, ported parts of it to PHP and released the library svg-sanitizer. He has also been kind enough to release the WordPress plugin Safe SVG that both enables SVG uploads and filter all uploaded SVG files through svg-sanitizer. Daryll is very clear on the fact that this is mostly to serve as a proof of concept, but it does seem to be good at sanitizing several attack vectors.

Chris Christoff also points out:

If WordPress were to ever allow SVGs, the sanitize library would not only need to work well, it would also need to be thoroughly tested, in large scale production environments. Literally by design, SVGs are designed to be insecure.

[…]

The second something like SVGs were to get into WordPress core, our library would be scrutinized, poked and prodded for security holes.

Remember that WordPress powers more than a quarter of all websites, so security isn’t something we can take lightly.

– Blah, blah, I still want SVG files

If you understand the risks, you know better than allowing users you don’t trust fully to upload SVG files. By “trust fully” I mean users who also understand the risks and know how to avoid them. You might have users who don’t have bad intentions, but who are willing to upload an SVG file they got from someone else.

But if you do trust all your users or simply have to accept the risk, please do not use a code snippet like the one at the beginning of this article. Please use the plugin Safe SVG instead. It will at least do some scrutinizing.

58 Comments

  1. What about all the rendering security issues with JPEG and PNG over the years? SVG is no worse of when it comes to accepting data from untrustworthy sources.

    1. SVG allows a lot of attack vectors by design, not by accident, so we’re not talking about unpatched security issues here. SVGs are really easy to exploit and the only “safe” way we can deal with them is to disallow features. JPEG and PNG are not designed to allow for e.g. arbitrary code execution.

      1. This is an overstatement.

        When SVG was designed, they didn’t say, “we need to include XSS! What can we do to include XSS? Billion Laughs is inherent in SVG entities, so we go that covered, right?”

        SVG is one of the older specifications (SVG 1.0 is coming up on its 15th anniversary, where was HTML 15 years ago?). We’re really only seeing it in common use now that all (most?) browsers have embedded support for it and its only been the last couple years that its become a regular tool in the toolbox.

        Like HTML, CSS and JS a lot of the initial work was somewhat naive either in the spec or in the implementations. How many vulnerabilities have been discovered in HTML, CSS and JavaScript in the last 15 years? How many of the SVG vulnerabilities are present in HTML or JavaScript (Billion Laughs, for example can be done in HTML or accomplished via JS just as easily).

        The issue , which @chriscct7 hyperbolically obscures, is that SVG is functioning code and it should be treated as such. SVG is a program, not an image. Fundamental flaws aside (and since it hasn’t been researched as extensively as HTML up to this point, there surely are some) SVG is not more inherently insecure than HTML is.

        What is at issue is that, unless you can find a reliable way to strip out the problematic bits, you should treat SVG from untrusted users the same way that you treat HTML from untrusted users.

      2. What if we used an SVG that was not downloaded from any website by created locally through illustrator. Is that vulnerable too?

    2. Oh c’mon, you’re being silly. Certainly JPG and PNG have had their flaws and security issues over the years but they’re not even comparable to SVG in that regard. I think you’re being disingenuous by saying SVG is “no worse”.

      1. He didn’t say it was no worse than an image file – he said it was no worse than HTML or Javascript and if your website is already running scripts that can be exploited (any admin can upload new scripts via; plugins/themes/editor/ftp) then it’s ‘silly’ to be concerned about something that (capabilities aside) is in most cases going to used for something simple like a logo, and created by someone you trust (because they are employed by you in one capacity of another).

        There’s other simple ways to attack a website that WordPress facilitates – outdated plugins, SQL injections from contact forms (for example). It does not ‘disallow’ any of these.

  2. Well, but what if you parse the SVG file and either strip malicious scripting or sanitize the markup?
    Of course this might give unexpected results if someone uploads an interactive SVG but this can be described as comment on the upload form and would allow SVGs to be uploaded still.

  3. Um, what?

    Yes, full SVG includes a lot of extra, potentially problematic features, but these do not apply when it is loaded in an image context, e.g. as the src of an img element. As explained on the W3C’s SVG Security page: https://www.w3.org/wiki/SVG_Security

    SVG in an image context cannot run any JavaScript. Nor can it load external resources, have hit testing, or add event listeners. If you find bugs or workarounds to these restrictions, then you should raise them as security issues with the appropriate browser vendor.

    If you really want vector graphics on the web, then you should be taking responsibility to enable SVG in a secure way in WordPress core, not leaving it to 3rd party plugins to address, based on spurious security concerns.

    1. Yeah, but once a malicious svg is inside your server a visitor just need to open it directly to run the code, just like visitors usually do with jpeg (right click > view image).

    1. This is a great idea. As someone who is investing a lot of time and effort pushing forward what is possible with SVG animation I’m concerned that SVG as a format has already been branded insecure. However it seems a suggestion like this could overcome those fears quite quickly and easily. Would having these two content types also be open to exploitation?

  4. Would one solution be a new web service that runs DOMPurify (maybe in a headless browser for access to real DOM internals) against SVG uploads? It could throw in OMGSVG for optimization as a bonus. Does this already exist? Anyone interested?

  5. If you are in danger of having a script tag in your SVG then you have not purchased or created it, and you definitely cannot say it’s responsibly sourced. So why care if the format is potentially vulnerable? It sounds like a job for browser vendors not end-users, responsible webmasters, responsible owners or responsible content creators.

    I made an SVG upload plugin for WP after Chris’s initial article as I couldn’t understand why WordPress did not support SVG with just the small filter. I linked it as a Gist and got some interest. A few weeks ago someone else wanted to contribute, so now it’s a fully fledged Github Repo that allows the use of uploading SVG to WordPress including site-logo and media gallery. It has risks for sure, as does HTML, JS and CSS; walking outside your house, having hobbies, having a life etc.

    The point being this should exist in WordPress. For now there are two plugins that provide SVG I know of; mine and one by @Grok, use either, be responsible and bug the WP core team to merge one of them into core.

    https://github.com/Lewiscowles1986/WordPressSVGPlugin
    https://github.com/grok/wordpress-plugin-scalable-vector-graphics

    1. > If you are in danger of having a script tag in your SVG then you have not purchased or created it, and you definitely cannot say it’s responsibly sourced. So why care if the format is potentially vulnerable?

      WordPress is not used only by developers and designers. There’s a lot of unskilled people using it and they don’t always know what they are uploading. They just need an image to their article and can find it on some shaddy free vector website.

      1. Hi guys,

        I wrote a plugin for WordPress to handle SVG uploads and also allows inline SVG with a simple CSS class added quite some time ago:
        https://wordpress.org/plugins/svg-support/
        It has a setting to only allow admins to upload SVG files which can help prevent other users you don’t trust uploading malicious files.

      2. Which is why allowing admins uploads is reasonable. They can already screw with all the code on the site.

  6. Could a URL rewrite of every .svg to a php script which outputs the file only if requested through WordPress be a possible solution?
    It could output simple HTML with an img tag if requested outside WP.
    That would secure your server through W3C’s SVG Security.

    While writing this I realised it would be a naive solution, as it’s up to every browser to follow the W3C’s Standards. I still posted, for the sake of discussion.

  7. Thanks for that! It seems so obvious now but it didn’t occur to me earlier.

    I always loved WordPress but hated it’s limitations, now I respect it for them.

    And didn’t know about the Safe SVG plugin, looks like something worth contributing to.

  8. I just tried to upload an SVG via WordPress media uploader, and then promptly searched for answers! Thanks for clearing the whole thing up! Do you think we need a vector format that is equally as open but designed for the purpose? So all the benefits of scalable vector graphics, but without the ability to inject code so easily?
    WVF… Web Vector Format… ;)

  9. Hi Bjorn,

    thank you for your explanation.
    I have a question regarding the source of an svg: Can I assume, if the svg is generated by me and therefore not from an unknown source, it’s use in wordpress isn’t a problem?

    Regards, Neal

  10. From “SVG files are extremely unsecure.” to “Sure, if you generated it yourself, there’s no problem at all” in one article :-)
    So what are we talking about? SVG being an unsafe format when you just download SVG’s from the Internet to use them in a website or allow any users to upload SVG’s to a website. Yeah, that’s pretty unsafe, but why would you even do or allow that in the first place? For SVG’s that you created yourself based on a vector design (e.g. a logo, icons) I don’t see the problem. Quite the opposite, for images that are part of a theme, where SVG can provide good scalability, it even might be the best format.

    1. We are talking about why WordPress don’t allow uploading SVG files by default, and while there are quick fixes for this, maybe you need to give it a second thought before doing so. SVGs should be treated like you treat JS files; if you trust the source, no problem. But most people don’t know this. They believe it’s simply a vector image format.

      1. No problem. It’s good to raise awareness. I would have gone for a less sensational headline and would have made more obvious that SVG can perfectly be used in a responsible way too.

        1. I completely agree with you man, this article is misleading. It should be clarified from the start that this pertains to SVG files from unknown sources. If I haven’t read the comments I wouldn’t know, I’d only assume that SVGs are a gateway for hacking regardless if I got it online or if I generated it myself. I’m glad that I read the comments section. I think this is spreading the wrong idea about SVG formats.

          1. Thanks for your comment. What part of the article did you find misleading, by the way?

          2. I think its the part that you left out the information that only SVG files from unknown sources are harmful. For a reader like myself who is relatively new with wordpress or SVGs, we can easily misinterpret the information that you shared and assume that ALL SVG files..regardless where they came from is harmful for WP websites.

          3. Perhaps you can add that disclaimer somewhere, most of us who search for articles like this already have our own SVG files.

  11. Can’t and SVG be used in a WP plugin safely. I am wanting to use a SVG to create an graphic that the user can change it’s color and size with javascript. The plugin would not let anyone upload a SVG.

    1. Sure. The issue is with arbitrary SVG uploads from arbitrary users.

      1. You could substitute almost anything for ‘SVG’ here…
        Arbitrary and un-sanitised Anything from arbitrary uses is dangerous.
        Even plain text – I can just write rude things!

  12. Hej Bjørn

    Thanks for this article. I think I am commenting on a similar issue to others. If I understand correctly, it isn’t SVG files per se that are the problem. It is the fact that they *could* have malicious code embedded in them. Is that correct?

    So, if we have control over which SVG files are used (as in ones we make ourselves for example), then there would be no issue.

    Would be great if you can shed light on that.

    Thanks

  13. Thanks for sharing this info, Bjørn. Would have never thought SVG carries such security issue as a graphic/web designer. Like you mentioned in this article, most people will think of it as a vector format.

  14. I found a solution! Use fonttastic.me to turn your SVG icons into a font so you can use them on your site.

  15. So just to really get the point straight… I am a graphic designer. I want to use an SVG logo not a raster PNG as a logo in my WordPress website. So, I create my own vector logo in illustrator. I then “Save As” a SVG file. [note FYI some handy settings here:
    http://razreye.com/blog/2014/09/15/using-svg-images-wordpress/ ]

    (Oh, I know I can view it anytime by just dropping the file it into any browser window, and see how beautiful and scalable it is. Swoon.)

    Then I install a wordpress plug in ( ie. a legit one from no less the official wordpress plugin directory eg “SVG Support” or “Safe SVG”) More importantly I make sure I set the settings that only Admins can upload SVG files – so thats “SVG Support” (as I dont want to pay for the pro-version of “Safe SVG”)

    I upload my SVG file. So I reckon (as I made the logo totally from scratch myself) I am good to go! So do I understand my website is safe from now on? OK – just saying… is it possible for some hack to then corrupt my safe little logo’s code somehow and cause chaos and havoc on my website?? Please tell me I have nothing to fear.

    Oh BTW, apart from the scare factor, your article is great!

    1. Hi Georgina! As long as you create the SVG files yourself, and only people you trust – and know that they should only upload SVG files they created themselves – can upload SVG files you’ll be perfectly fine :-)

      Sorry about the scare factor. But the internet is a scary place :-o

  16. No worries! You are right to point everything out! Thanks for being so thorough! :-)

  17. I just recently found out that .svg files poses severe security ussies. :( I’ve been using .svg files on my sites for years.

    As I understand from your article svg is the same as a .js file. They can both be secure or they can both enable XSS for instance.

    First question.
    If I downloaded a shady .svg file and then opened it in Illustrator and resave it into an illustrator file (*.ai) and then into a .svg file. Is this new .svg file fully sanitized?

    Second question.
    What about SVG versions? Is any of them safe?
    SVG 1.0
    SVG 1.1
    SVG Tiny 1.1
    SVG Tiny 1.1 +
    SVG Basic 1.1
    SVG Tiny 1.2
    SVG Mobile 1.1

    Thank you for the explanation.

  18. Thanks for explaining why SVG file uploads are disabled by default in WordPress! I wasn’t fully aware of the risks before reading your post, but now I’m suddenly very glad my pedantic side has made me run all the SVG files I use through optimizers that strip out unnecessary code :)

  19. Hi Bjørn. Thanks for this great article which gave a serious impact just a few seconds before I started to make some changes. I’ve gone through the feedback by Neal Mibe carefully, and your reply too. The feedback was focused on ‘self-produced SVG’ topic. Here is my little wondering: Will SVGs which are produced by myself still be used as an attack point against visitors?

  20. Just ruminating here, so as I see it, most people are using this for the logo display.

    So if the svg file is generated by the admin/owner-whomever, it could be considered “safe” but then, in order to get around the default WordPress denial of uploading, the same people have add a plugin that will allow the support of svg uploads ( I am assuming here the the plugin simply allow the WP install to accept an svg upload ).

    I am also assuming that…. if a properly formatted svg file can be viewed in a browser window, the only inhibiting factor to this is the upload process, right?

    So… why not use the ftp protocol to upload a file to a pre-determined location (dir) and simply add the document path to the image location? That cant be too difficult as the admin person has control over the content/plugins.options etc… ? or is there more to the equasion as this remedy has worked well for me.

    One thing I have noticed though, sometimes the resulting svg is completely black, and drops all colors, gradients etc.

    PS: outline the fonts, folks :)

  21. thank you so much. I was on this SVG issue for some days now and tried nearly everything. Until I installed the Safe SVG plugin. (”is the best way to Allow SVG Uploads in WordPress!”) It worked instantly.

  22. Thanks for a clear and informative explanation of this issue. with links to even more info. you answered the broad strokes in moments. 👍

  23. I had the same problem on a site and was looking for a solution, your code is save my life :-)

  24. Hi Bjørn,

    I stumbled across your article researching safer alternatives in limiting the threats SVGs can pose. Out of curiosity, what are the possible mitigations?

    Jake Archibald mentions the use of content security policies. I am making a reasonable leap and assumption that if the content security policy restricts the execution of binaries and/or scripts to ‘self’ that the risk of a compromise is dramatically reduced.

    The additional considerations would be if these scripts/binaries exploit vulnerabilities in either the application or operating system stack. Again, I presume these would be largely mitigated as a result of strict content security policies.

    For example, the default CSP I reference in project is as follows. If SVGs were permitted, what additional controls should be considered with the policy below i.e. what else should be included or excluded?

    “base-uri ‘self’;”.
    “default-src ‘self’;”.
    “connect-src ‘self’ https://www.google-analytics.com;”.
    “child-src ‘self’ https://www.google.com;”.
    “frame-ancestors ‘self’ ;”.
    “frame-src ‘none’;”.
    “upgrade-insecure-requests;”.
    “block-all-mixed-content;”.
    “form-action ‘self’;”.
    “font-src ‘self’ https://fonts.googleapis.com https://fonts.gstatic.com data:;”.
    “media-src ‘none’;”
    “img-src ‘self’ https://secure.gravatar.com https://s.w.org https://ps.w.org data:;”.
    “object-src ‘none’;”.
    “style-src ‘self’ https://fonts.googleapis.com ‘nonce-“;”.
    “script-src ‘self’ https://maps.googleapis.com https://ajax.googleapis.com https://ajax.cloudflare.com https://static.cloudflareinsights.com https://cdnjs.cloudflare.com ‘nonce-“;”;//

  25. Hi Bjørn,
    I landed on your this post while I was looking for, why WP has added files in footer after the latest update to the version 5.9. I wondered why they guys keep adding these types of stuff. I request you put some light on my topic too.

    Many thanks,
    Freya, UK

Comments are closed.