[wp-trac] [WordPress Trac] #39963: MIME Alias Handling
WordPress Trac
noreply at wordpress.org
Fri Nov 10 22:43:55 UTC 2017
#39963: MIME Alias Handling
--------------------------------------+-----------------------------
Reporter: blobfolio | Owner:
Type: enhancement | Status: reopened
Priority: normal | Milestone: 5.0
Component: Media | Version:
Severity: normal | Resolution:
Keywords: has-patch has-unit-tests | Focuses: administration
--------------------------------------+-----------------------------
Comment (by blobfolio):
All rightie, got a new patch in place (`39963.diff` and a few files for
unit tests in `phpunit-data.zip`).
[[BR]]
'''Functions:'''
This patch includes 5 new functions.
[[BR]]
The file-renaming logic that sometimes happens during a file upload has
been abstracted into its own function, `wp_update_filename_extension()`.
This simply replaces the extension on the end of the file name.
{{{#!php
/**
* Assign a new extension to a filename.
*
* @since 5.0.0
*
* @param string $filename The original filename.
* @param string $ext The new extension.
* @return string The renamed file.
*/
function wp_update_filename_extension( $filename, $ext ) {
}}}
[[BR]]
In terms of actual MIME alias work, the most basic check is
`wp_check_mime_alias()`, which is used to see whether or not a given MIME
type is appropriate for a given file extension.
{{{#!php
/**
* Check extension and MIME pairing.
*
* @since 5.0.0
*
* @param string $ext File extension.
* @param string $mime MIME type.
* @return bool True/false.
*/
function wp_check_mime_alias( $ext = '', $mime = '' ) {
}}}
[[BR]]
To go a little deeper, we have `wp_check_allowed_mime_aliases()`, which
checks to see whether a given MIME type is in the official `upload_mimes`
list, or is an alias of a type that is in that list. ''The `upload_mimes`
types always take priority.'' This will return an array with `ext` and
`type` keys (the type being the official whitelist entry) if it is
allowed, otherwise `false`.
{{{#!php
/**
* Check Allowed Aliases
*
* This will cycle through each allowed ext/MIME pair to see if an alias
* matches anything.
*
* @since 5.0.0
*
* @param string $alias MIME alias.
* @param array $mimes Allowed MIME types.
* @return array|bool Array containing ext and type keys or false.
*/
function wp_check_allowed_mime_aliases( $alias, $mimes = null ) {
}}}
[[BR]]
Finally, we have a function that applies this alias-matching to an actual
file. This uses a tiered approach to determine the best guess about what
kind of a file a file actually is, and whether or not it is allowed by WP.
This staged approach begins with a basic call to `wp_check_filetype()`,
which determines type solely based on the file name. After that it will
evaluate content via `EXIF` and `fileinfo.so` (if it is able to do so). If
the "real" MIME differs from the name-based MIME, alias matching comes
into play, and if that file is still allowed, the `ext` and `type`
returned are updated accordingly to match reality.
Like the original `wp_check_filetype()` function, invalid/illegal files
result in an array with `ext` and `type` set to `false` being returned.
{{{#!php
/**
* Retrieve the "real" file type from the file.
*
* This extends `wp_check_filetype()` to additionally consider content-
* based indicators of a file's true type.
*
* The content-based type will override the name-based type if available
* and included in the $mimes list.
*
* A false response will be set if the extension is not allowed, or if a
* "real MIME" was found and that MIME is not allowed.
*
* @since 5.0.0
*
* @see wp_check_filetype()
* @see wp_check_filetype_and_ext()
*
* @param string $file Full path to the file.
* @param string $filename The name of the file (may differ from $file due
to $file being in a tmp directory).
* @param array $mimes Optional. Key is the file extension with value
as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_real_filetype( $file, $filename = null, $mimes = null )
{
}}}
[[BR]]
And last but not least, we have a function that returns the full database
of MIME aliases, which is auto-generated and stored in `wp-includes/media-
mimes.php`. This data is an array, each key is a file extension, the
values are arrays of MIME type(s) for said extension.
{{{#!php
/**
* Return MIME Aliases
*
* @since 5.0.0
*
* @return array MIME aliases organized by file extension. See data below
for example.
*/
function wp_get_mime_aliases() {
}}}
[[BR]]
'''Filters:'''
Many of these new functions have eponymous filters that users can hook
into to change the results:
* `wp_get_mime_aliases`
* `wp_check_real_filetype`
* `wp_check_mime_alias`
There is one additional filter that needs a bit of background:
Most libraries will assign a file type of `application/octet-stream` to
any file they don't understand. It is the equivalent of "I dunno." Because
of this, the `wp_check_mime_alias()` function implicitly passes (i.e.
returns `true`) for any extension paired with this unhelpful type.
The filter `wp_check_mime_alias_application_octet_stream` was added to
allow users to decide whether or not `application/octet-stream` deserves
full checks or not. (`true` means actually check this, `false` (the
default) means don't worry.)
[[BR]]
'''Behavior:'''
The behavioral changes from this patch all stem from modifications to the
existing `wp_check_filetype_and_ext()` function, which is called as part
of the file upload process.
Previously, that function ran some content-based checks on certain types
of files, but did so in a way that resulted in false positives and
negatives.
Now that functionality is offloaded to `wp_check_real_filetype()`.
First and foremost, this means that ''all'' uploaded files are now
subjected to content-based analysis (for environments that support it).
This fixes the security issues the changes in `4.7.1` were meant to
handle, but also expands them to fix a lot of similar, unpublished issues.
This also means that WordPress can now intelligently rename files that are
using the wrong extension (but are otherwise allowed).
[[BR]]
'''Testing:'''
This functionality has existed in the `Lord of the Files` plugin for some
time and worked wonders there, but please give this patch a shot to make
sure it behaves the same way. (Also, be sure to deactivate `LotF` if it is
installed on your test sites.)
For those interested in checking out the build script (that compiles the
`media-mimes.php` file), you can find that at https://github.com/Blobfolio
/wp-blob-mimes.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/39963#comment:37>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list