Make WordPress Core

Changeset 43993


Ignore:
Timestamp:
12/12/2018 11:10:04 PM (5 years ago)
Author:
jeremyfelt
Message:

Media: Improve verification of MIME file types.

Merges [43988] to the 4.5 branch.

Location:
branches/4.5
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/4.5

  • branches/4.5/src/wp-includes/functions.php

    r43397 r43993  
    23252325            }
    23262326        }
    2327     } elseif ( function_exists( 'finfo_file' ) ) {
    2328         // Use finfo_file if available to validate non-image files.
     2327    }
     2328
     2329    // Validate files that didn't get validated during previous checks.
     2330    if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
    23292331        $finfo = finfo_open( FILEINFO_MIME_TYPE );
    23302332        $real_mime = finfo_file( $finfo, $file );
    23312333        finfo_close( $finfo );
    23322334
    2333         // If the extension does not match the file's real type, return false.
    2334         if ( $real_mime !== $type ) {
     2335        // fileinfo often misidentifies obscure files as one of these types
     2336        $nonspecific_types = array(
     2337            'application/octet-stream',
     2338            'application/encrypted',
     2339            'application/CDFV2-encrypted',
     2340            'application/zip',
     2341        );
     2342
     2343        /*
     2344         * If $real_mime doesn't match the content type we're expecting from the file's extension,
     2345         * we need to do some additional vetting. Media types and those listed in $nonspecific_types are
     2346         * allowed some leeway, but anything else must exactly match the real content type.
     2347         */
     2348        if ( in_array( $real_mime, $nonspecific_types, true ) ) {
     2349            // File is a non-specific binary type. That's ok if it's a type that generally tends to be binary.
     2350            if ( !in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ) ) ) {
     2351                $type = $ext = false;
     2352            }
     2353        } elseif ( 0 === strpos( $real_mime, 'video/' ) || 0 === strpos( $real_mime, 'audio/' ) ) {
     2354            /*
     2355             * For these types, only the major type must match the real value.
     2356             * This means that common mismatches are forgiven: application/vnd.apple.numbers is often misidentified as application/zip,
     2357             * and some media files are commonly named with the wrong extension (.mov instead of .mp4)
     2358             */
     2359
     2360            if ( substr( $real_mime, 0, strcspn( $real_mime, '/' ) ) !== substr( $type, 0, strcspn( $type, '/' ) ) ) {
     2361                $type = $ext = false;
     2362            }
     2363        } else {
     2364            if ( $type !== $real_mime ) {
     2365                /*
     2366                 * Everything else including image/* and application/*:
     2367                 * If the real content type doesn't match the file extension, assume it's dangerous.
     2368                 */
     2369                $type = $ext = false;
     2370            }
     2371
     2372        }
     2373    }
     2374
     2375    // The mime type must be allowed
     2376    if ( $type ) {
     2377        $allowed = get_allowed_mime_types();
     2378
     2379        if ( ! in_array( $type, $allowed ) ) {
    23352380            $type = $ext = false;
    23362381        }
  • branches/4.5/tests/phpunit/tests/functions.php

    r36883 r43993  
    462462                true,
    463463            ),
    464             // Android 2.2, Android Webkit Browser 
     464            // Android 2.2, Android Webkit Browser
    465465            array(
    466466                'Mozilla/5.0 (Android 2.2; Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4',
    467467                true,
    468468            ),
    469             // BlackBerry 9900, BlackBerry browser 
     469            // BlackBerry 9900, BlackBerry browser
    470470            array(
    471471                'Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+',
     
    481481                'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0',
    482482                true,
     483            ),
     484            // Non-image file not allowed even if it's named like one.
     485            array(
     486                DIR_TESTDATA . '/export/crazy-cdata.xml',
     487                'crazy-cdata.jpg',
     488                array(
     489                    'ext' => false,
     490                    'type' => false,
     491                    'proper_filename' => false,
     492                ),
     493            ),
     494            // Non-image file not allowed if it's named like something else.
     495            array(
     496                DIR_TESTDATA . '/export/crazy-cdata.xml',
     497                'crazy-cdata.doc',
     498                array(
     499                    'ext' => false,
     500                    'type' => false,
     501                    'proper_filename' => false,
     502                ),
    483503            ),
    484504        );
Note: See TracChangeset for help on using the changeset viewer.