12-10-2017 8-48-52 PM-v2

Fix “Sorry, This File Type Is Not Permitted For Security Reasons” Error in WordPress

So you’re trying to upload an otherwise harmless file into WordPress, and you keep getting a “Sorry, This File Type Is Not Permitted For Security Reasons” error.  Sure you could just upload the file via FTP, but it wouldn’t be attached to anything in the WP database.  Now what do you do?

There are probably many ways to solve this, but here is the approach that worked best for my particular use case.  I’ll share it here in case it helps someone else too.

First, a quick bit of background.

In this case I was working on a WordPress plugin where the user must be able to upload and attach a .ttf font file, using the built-in WP upload functionality.  This particular plugin is used by thousands of people across all different versions of WordPress, so I needed solution that would work the same in 4.7 as in 4.9.

For what it’s worth, file uploads have been an ongoing pain since WP version 4.7.1 introduced a bug with mime type validation, which was supposed to be fixed in 4.7.3 but instead was compounded, made worse, and now is not expected to be fixed until version 5.0:(

So here’s my solution:

function bear_adds_font_mimes( $mimes ) {
	$mimes = array_merge($mimes, array(
		'ttf' => 'application/octet-stream',
		'ttf|ttf' => 'application/x-font-ttf',
		'ttf|ttf|ttf' => 'application/font-sfnt',
	));
	return $mimes;
}
add_filter( 'upload_mimes', 'bear_adds_font_mimes' );

Now some explanation is in order. I’m using the WP filter upload_mimes to add some extra file type / mime type pairs to the associative array $mimes. Normally this is pretty simple — the array key is the file extension (separated by a pipe symbol, if multiple extensions); the array value is the mime type.

However, depending on the server you might get different mime types for the same file! So, how can we account for all of them? For example, I found that a .ttf file could come through as either a generic application/octet-stream, or application/x-font-ttf. Although I didn’t see it in practice, the spec says it could also be a application/font-sfnt. So you might be inclined to just do something like this:

// Don't do this:
$mimes = array_merge($mimes, array(
	'ttf' => 'application/octet-stream',
	'ttf' => 'application/x-font-ttf',
	'ttf' => 'application/font-sfnt',
));

… but this is wrong, because you can’t have 3 distinct values with same array key, in this case ‘ttf’. My first thought was just to make up some unique keys, like this:

// Don't do this either:
$mimes = array_merge($mimes, array(
	'ttf1' => 'application/octet-stream',
	'ttf2' => 'application/x-font-ttf',
	'ttf3' => 'application/font-sfnt',
));

… technically this “works” in WordPress 4.9, because if you look at the function wp_check_filetype_and_ext() it only uses in_array() to check if the value exists, not the key. But I can’t guarantee this will continue to work in future WP versions, and I definitely wouldn’t rely on it.

So my (admittedly hacky, but I think better) solution was to take advantage of the fact you can separate multiple extensions with a pipe (“|”) symbol. There doesn’t appear to be any harm in repeating the extension more than once, and this way you are at least using the legitimate extension instead of a made up one. Hence:

$mimes = array_merge($mimes, array(
	'ttf' => 'application/octet-stream',
	'ttf|ttf' => 'application/x-font-ttf',
	'ttf|ttf|ttf' => 'application/font-sfnt',
	// as so on...
));

That’s how I solved the problem for .ttf files. If your situtaion involves some other file type, you can simply modify my solution with the extension/mime type pairs for your particular needs. Here’s a good resource for looking up MIME types.

Hopefully this approach helps you, as it did me!

Leave a Reply

Your email address will not be published. Required fields are marked *