Media: Improve verification of MIME file types.
Merges [43988] to the 4.4 branch. Built from https://develop.svn.wordpress.org/branches/4.4@43995 git-svn-id: http://core.svn.wordpress.org/branches/4.4@43827 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
40f9e10d03
commit
60dacc5deb
|
@ -2242,14 +2242,59 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
|
||||||
$type = $ext = false;
|
$type = $ext = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif ( function_exists( 'finfo_file' ) ) {
|
}
|
||||||
// Use finfo_file if available to validate non-image files.
|
|
||||||
|
// Validate files that didn't get validated during previous checks.
|
||||||
|
if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
|
||||||
$finfo = finfo_open( FILEINFO_MIME_TYPE );
|
$finfo = finfo_open( FILEINFO_MIME_TYPE );
|
||||||
$real_mime = finfo_file( $finfo, $file );
|
$real_mime = finfo_file( $finfo, $file );
|
||||||
finfo_close( $finfo );
|
finfo_close( $finfo );
|
||||||
|
|
||||||
// If the extension does not match the file's real type, return false.
|
// fileinfo often misidentifies obscure files as one of these types
|
||||||
if ( $real_mime !== $type ) {
|
$nonspecific_types = array(
|
||||||
|
'application/octet-stream',
|
||||||
|
'application/encrypted',
|
||||||
|
'application/CDFV2-encrypted',
|
||||||
|
'application/zip',
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
$type = $ext = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue