In web development, when you want to import or export files from a server to a client, or vice versa, you will transfer such files through the HTTP protocol. In both cases, the HTTP request or response usually declares which kind of content they’re transfering.
I’d use an a comparison to explain it easier : when a stranger knocks at your door, you’d rather know which kind of stranger is knocking. Knowing that he is either a policeman or a salesman would prepare you a little more to what to expect from such a stranger.
This is the same for both clients and servers. And HTTP uses the same syntax to declare such content than several other internet protocols, which is called MIME.1
WordPress can be your door keeper
WordPress currently has function to verify validity of a filename called wp_check_filetype()
2. It will basically check a provided file name against every kind of existing file extensions registered in WordPress, and then return an array containing the matched extension (if any), and its corresponding MIME type declaration.
If you take a look at the long list of registered extensions, you may notice that the xml
file type is absent. It may seem curious but it’s indeed very reasonable to do so : XML being a very flexible format, it can introduce several kind of vulnerabilities in your website.3 4
Your home, your rules
Now let’s say you want to interact with XML in your plugin, in such a case you will be in charge of enforcing XML security. There are several vulnerabilities to take into consideration but I won’t list them here. You still have the possiblity to use wp_check_filetype()
with a custom set of extensions.
The first solution is through a wordpress hook, there are two avalaible:
mime_types
is the most generic one, as it will return the full list of the default WordPress registered MIME types. Although, it is warned that should not use it to remove MIME types with this hook, instead use the following one.upload_mimes
: The benefits of this filter is that it has already been filtered to exclude html MIME types except for users with the capabilityunfiltered_html
5, this means from editor roles up to super administrator.
Now if you use this hook, this means that the MIME type you added will be considered as valid in the whole WordPress instance, and not just your plugin. This is definitely not what we want, as we can’t expect every plugin and theme author to have secured their code against vulnerabilities that can come along with the MIME type that you’ve added.
You still can do it
So in order to use wp_check_filetype()
in your code, the best way would be to supply your own array of file extensions / MIME types 6 pairs as the second parameter of this function. Then it will validate the file name only against this array you have provided, regardless of the WordPress default registered MIME types.
You may still use this default list by calling the wp_get_mime_types()
function, or the get_allowed_mime_types()
and provide the current user as first parameter if you want to benefits from the default filtering. Then you can merge it with your added MIME types. It just depends on what you are trying to achieve.
Sylvain Schellenberger