↳ Notes

Allowing SVG uploads in WordPress

SVG is a very popular format for adding various graphics to the web, such as logos, icons and other drawings. It has the advantage of being data-efficient and keeping its quality even when resized (when you enlarge a JPG or PNG beyond its dimensions it starts to get pixelated, which doesn’t happen with SVG). But if you try to upload it to WordPress, you’ll probably run into a message saying you don’t have sufficient permission to upload this file type.

WordPress insufficient permission

Fortunately, this can be worked around with various plugins, or with a simple snippet.

add_filter('upload_mimes', 'lh_enable_svg_upload', 10, 1);
function lh_enable_svg_upload($mimes) {
  if (!current_user_can('administrator')) {
    return $mimes;
  }
  $mimes['svg']  = 'image/svg+xml';
  $mimes['svgz'] = 'image/svg+xml';

  return $mimes;
}

The snippet above allows all users in the administrator role to upload SVG images. If you want to allow uploads for everyone, remove the section:

if (!current_user_can('administrator')) {
    return $mimes;
}

However, this section is here for security reasons (see below).

Why is SVG disabled by default?

SVG is a structured XML document, which is something similar to HTML, in which we store the structure of web pages. And just like into HTML, you can also smuggle, say, some malicious JavaScript into an SVG. As an example, here’s an SVG image depicting a blue circle, complete with “malicious” JavaScript:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   width="200"
   height="200"
   viewBox="0 0 52.916665 52.916668"
   version="1.1"
   id="svg5"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <defs
     id="defs2" />
  <g
     id="layer1">
    <ellipse
       style="fill:#0000ff;stroke-width:1.24804"
       id="path868"
       cx="26.268953"
       cy="26.447653"
       rx="23.052345"
       ry="21.801445" />
  </g>
  <script>
  if (confirm('Ať zmáčknete co zmáčknete, stejně vás přesměruji.') == true) {
    window.location.replace("https://www.hilgert.cz/");
  } else {
    window.location.replace("https://www.hilgert.cz/");
  }
  </script>
</svg> 

You can try it out for yourself here https://www.ksefticek.cz/skodlive-kolecko/. You may have wondered why anyone would install a plugin when a few lines of code in your active theme’s functions.php are enough. The thing is, plugins usually check the uploaded SVG and catch nasties like this, or minify the uploaded SVG and so on. If you build the site yourself and need to upload a few of your own or vetted SVG images, I’d probably go the few-lines-of-code route. If you don’t have full control over what gets uploaded, then a plugin is worth considering.

Not all SVGs are the same

Put the code mentioned above into functions.php and the image still won’t upload? The thing is, not all SVGs are the same. Notice the image/svg+xml in the code. That denotes the file type, and you can come across both the already-mentioned image/svg+xml and image/svg. So if the SVG image still won’t upload, you probably have the second type. You can verify this by opening the image in, for example, Notepad. If the first line has an XML declaration, it’s image/svg+xml; if it’s not there, it’s image/svg.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

You can delete or add this declaration as you like, and that gives you the desired file type.

↳ Note written by

Need to tweak your website?

I'm not a fan of dozens of plugins that slow a website down. Wherever I can, I solve it with clean code - without unnecessary extra weight.

Discuss a website edit