Media: Improve verification of MIME file types.
Merges [43988] to trunk. git-svn-id: https://develop.svn.wordpress.org/trunk@44292 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
07cf8f3073
commit
06f2b3f5bc
@ -2545,17 +2545,51 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
|
||||
$real_mime = finfo_file( $finfo, $file );
|
||||
finfo_close( $finfo );
|
||||
|
||||
/*
|
||||
* If $real_mime doesn't match what we're expecting, we need to do some extra
|
||||
* vetting of application mime types to make sure this type of file is allowed.
|
||||
* Other mime types are assumed to be safe, but should be considered unverified.
|
||||
*/
|
||||
if ( $real_mime && ( $real_mime !== $type ) && ( 0 === strpos( $real_mime, 'application' ) ) ) {
|
||||
$allowed = get_allowed_mime_types();
|
||||
// fileinfo often misidentifies obscure files as one of these types
|
||||
$nonspecific_types = array(
|
||||
'application/octet-stream',
|
||||
'application/encrypted',
|
||||
'application/CDFV2-encrypted',
|
||||
'application/zip',
|
||||
);
|
||||
|
||||
if ( ! in_array( $real_mime, $allowed ) ) {
|
||||
/*
|
||||
* If $real_mime doesn't match the content type we're expecting from the file's extension,
|
||||
* we need to do some additional vetting. Media types and those listed in $nonspecific_types are
|
||||
* allowed some leeway, but anything else must exactly match the real content type.
|
||||
*/
|
||||
if ( in_array( $real_mime, $nonspecific_types, true ) ) {
|
||||
// File is a non-specific binary type. That's ok if it's a type that generally tends to be binary.
|
||||
if ( ! in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ) ) ) {
|
||||
$type = $ext = false;
|
||||
}
|
||||
} elseif ( 0 === strpos( $real_mime, 'video/' ) || 0 === strpos( $real_mime, 'audio/' ) ) {
|
||||
/*
|
||||
* For these types, only the major type must match the real value.
|
||||
* This means that common mismatches are forgiven: application/vnd.apple.numbers is often misidentified as application/zip,
|
||||
* and some media files are commonly named with the wrong extension (.mov instead of .mp4)
|
||||
*/
|
||||
|
||||
if ( substr( $real_mime, 0, strcspn( $real_mime, '/' ) ) !== substr( $type, 0, strcspn( $type, '/' ) ) ) {
|
||||
$type = $ext = false;
|
||||
}
|
||||
} else {
|
||||
if ( $type !== $real_mime ) {
|
||||
/*
|
||||
* Everything else including image/* and application/*:
|
||||
* If the real content type doesn't match the file extension, assume it's dangerous.
|
||||
*/
|
||||
$type = $ext = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The mime type must be allowed
|
||||
if ( $type ) {
|
||||
$allowed = get_allowed_mime_types();
|
||||
|
||||
if ( ! in_array( $type, $allowed ) ) {
|
||||
$type = $ext = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1301,8 +1301,8 @@ class Tests_Functions extends WP_UnitTestCase {
|
||||
DIR_TESTDATA . '/formatting/big5.txt',
|
||||
'big5.jpg',
|
||||
array(
|
||||
'ext' => 'jpg',
|
||||
'type' => 'image/jpeg',
|
||||
'ext' => false,
|
||||
'type' => false,
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
@ -1316,6 +1316,26 @@ class Tests_Functions extends WP_UnitTestCase {
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
// Non-image file not allowed even if it's named like one.
|
||||
array(
|
||||
DIR_TESTDATA . '/export/crazy-cdata.xml',
|
||||
'crazy-cdata.jpg',
|
||||
array(
|
||||
'ext' => false,
|
||||
'type' => false,
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
// Non-image file not allowed if it's named like something else.
|
||||
array(
|
||||
DIR_TESTDATA . '/export/crazy-cdata.xml',
|
||||
'crazy-cdata.doc',
|
||||
array(
|
||||
'ext' => false,
|
||||
'type' => false,
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Test a few additional file types on single sites.
|
||||
|
Loading…
Reference in New Issue
Block a user