16

I have a snippet in my functions PHP file that allows me to upload SVG files. Since upgrading to the latest version of WP today, I can no longer upload svgs. I also tried a second code snippet from CSS tricks website and that doesn't work either.

Does anyone know a) what may have caused this with the last update and b) Does anyone know a work around.

Here is the code I normally use:

function svg_mime_types( $mimes ) {
   mimes['svg'] = 'image/svg+xml';
   return $mimes;}
add_filter( 'upload_mimes', 'svg_mime_types' );  

Many thanks

Paul.

16

In WordPress 4.7.1 a change was introduced that checks for the real mime type of an uploaded file. This breaks uploading file types like SVG or DOCX. There already exist tickets for this issue in WordPress Core, where you can read more about this:

A temporary and recommended workaround (for the time until this issue is fixed) is the following plugin:
Disable Real MIME Check

If you don’t want to use that plugin, here’s the same functionality:

add_filter( 'wp_check_filetype_and_ext', function($data, $file, $filename, $mimes) {
    global $wp_version;

    if ( '4.7.2' !== $wp_version ) {
       return $data;
    }

    $filetype = wp_check_filetype( $filename, $mimes );

    return [
        'ext'             => $filetype['ext'],
        'type'            => $filetype['type'],
        'proper_filename' => $data['proper_filename']
    ];

}, 10, 4 );

Notice that this snipped has a version check included to disable the fix as soon as WordPress is updated.

Edit

The issue was initially set to be fixed in 4.7.2. But since 4.7.2 was an urgent security release, the fix didn’t make it into that version. It’s now supposed to be fixed in 4.7.3.

  • 2
    Alternative workaround for development environments: add define( 'ALLOW_UNFILTERED_UPLOADS', true ); to wp-config.php. This is not safe for production. – Tim Malone Jan 12 '17 at 23:51
  • 1
    Just to collect all info in one place, here's a related forum thread too: wordpress.org/support/topic/wp-4-7-1-kills-svg – Tim Malone Jan 12 '17 at 23:52
  • Thanks for this. It's not an urgent situation at the moment, but it's good to know there is a work around. Very much appreciated. – Paul12_ Jan 13 '17 at 1:11
  • Introduces too wide ranging effects unless it checks specifically for 'svg' === strtolower($filetype['ext']); and introduces more work in the case no work is needed (mostly) or the file is not of type svg... – MrMesees Jan 20 '17 at 10:58
4

Seems like this might be related to this ticket https://core.trac.wordpress.org/ticket/39552, looks like something that got broken in 4.7.1

  • Ah thanks Mark. I thought something was wrong. Hopefully it'll be fixed soon. – Paul12_ Jan 12 '17 at 18:28
2

Nobody seems to have just worked with what is and that's too bad so here's how I handled...

History / Background

I created a SVG uploader in 2015 based upon a CSS-Tricks article looking at what was. I Also got grid working for image preview, and used a few other fixes. Simple plugin (IMO file-type plugins should be simple)

Solution

There were a few changes for 4.7. The real PITA was that for image/ mime types WP is now using GD on the images. To bypass this I set the svg extension to use application/svg+xml so GD wouldn't mess with the file.

Update: as of 4.7.2 some bright spark broke that too in some cases

Then later via hook we hotwire it back to image/svg+xml. It is the same used in other answers, but we firstly lock it down to our specific case to eliminate effects (is it an SVG file); we can rely on reading $data['ext'] (should be cheaper than the function to get file info as only one comparison and one array / hash access).

Update: as of 4.7.2 $data['ext'] is not always set, so we now if it's length is < 1 extract (potentially unsafe) extension from the filename using strtolower(end(explode('.', $filename))). The reason I'm really fighting using FileInfo is that essentially relying on a PHP extension is too opaque and won't always work for everyone (especially not those compiling without or without access to enable extensions if it's not there). I'd like something that works in-lieu of an extension. It's no longer a matter of having the correct information so for those trusting the output of FileInfo and having the extension (I believe it's default in 5.6+) it should work. Also because this is a plugin, it's not modifying core you can turn off this code or unregister the hook.

https://github.com/Lewiscowles1986/WordPressSVGPlugin

See

Other workarounds

Allowing unfiltered uploads is a horrible solution because as others have said linking to this thread people could upload php files via media uploader (that's bad and if you do it, you should stop and think!)

Forcing every file through any function without checks (Ironically if you have image/ in the mime type you can't just have a simple ext check). This has the potential to create far wider reaching effects to solve a relatively niche problem and introduces more work overall (caveat my plugin also introduces more work for admin users to get admin media UI to work)

If we left the mime as application/svg+xml and simply filtered the mime types the image would upload but would AFAIK require fixes to be used as a featured image etc. There is more work to be done on ensuring universal SVG experience so I chose to pick battles carefully.

Hope this helps.

  • well, the core issue driving this whole thing is the fact that there is no moderation before uploaded files are being published. trying to guess if a file is evil basically just based on its extension is always a bad idea. in theory there is no problem with allowing all uploads by admin so while some of the suggested fixes might be generally too wide, in practice they might be good enough for many people. Side note IMHO SVG is as much of an image as a PDF, technically it is not. – Mark Kaplun Jan 20 '17 at 11:28
  • whoever came up with mime-types disagree's with you, as do browser vendors and software producers the world over. WordPress only checks extensions because it's not intended as a piece of network security and that's okay (for the same reason microsoft office doesn't park your car). It's hyperbolic at least to say WP should do much more checking than superficial but I agree there needs to be more security work, just not that WP is an appropriate vehicle for that work (it's almost too big as-is) – MrMesees Jan 20 '17 at 14:27
  • actually browsers do inspection of the content in all kinds of situations developer.mozilla.org/en-US/docs/Mozilla/… and they never look at the extension. And yes no one expects wordpress at this point to have a focus on hardening security ;) – Mark Kaplun Jan 20 '17 at 16:16
  • First thing, one blog article of one browser != all browsers. I Know Chrome pays attention to mime. Second thing, the introspection of files follows rules; it's not free form as the loose language suggests. More comprehensive validation trades performance for flexibility (it works on single PC level clients, not multi-user public offerings). To evidence this open Firefox, open 100 tabs look at memory & CPU usage. Try the same with 100 requests for a website! Last thing please stop unless you have some actual facts to add not digressions. It's quite aggravating and is not benefiting anyone. – MrMesees Jan 20 '17 at 18:03
  • inspecting the 256 first bytes of a just uploaded file will inure almost zero performance hit as the file is probably in memory or SSD cache, and it pales in any case when you compare it to the performance hit from resizing the files, generating thumbnail and what not. As for other browsers, not exactly in the same code flow, but from this stackoverflow.com/questions/1201945/… it is not farfetched to assume that chrome and firefox are very much aligned – Mark Kaplun Jan 20 '17 at 18:31

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.