diff --git src/wp-includes/functions.php src/wp-includes/functions.php
index 865c0d29b59..ee214e923af 100644
--- src/wp-includes/functions.php
+++ src/wp-includes/functions.php
@@ -2269,15 +2269,15 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
 		return compact( 'ext', 'type', 'proper_filename' );
 	}
 
+	$real_mime = false;
+
 	// Validate image types.
 	if ( $type && 0 === strpos( $type, 'image/' ) ) {
 
 		// Attempt to figure out what type of image it actually is
 		$real_mime = wp_get_image_mime( $file );
 
-		if ( ! $real_mime ) {
-			$type = $ext = false;
-		} elseif ( $real_mime != $type ) {
+		if ( $real_mime && $real_mime != $type ) {
 			/**
 			 * Filters the list mapping image mime types to their respective extensions.
 			 *
@@ -2308,18 +2308,29 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
 				$ext = $wp_filetype['ext'];
 				$type = $wp_filetype['type'];
 			} else {
-				$type = $ext = false;
+				// Reset $real_mime and try validating again.
+				$real_mime = 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 );
 		$real_mime = finfo_file( $finfo, $file );
 		finfo_close( $finfo );
 
-		// If the extension does not match the file's real type, return false.
-		if ( $real_mime !== $type ) {
-			$type = $ext = false;
+		/*
+		 * 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();
+
+			if ( ! in_array( $real_mime, $allowed ) ) {
+				$type = $ext = false;
+			}
 		}
 	}
 
diff --git tests/phpunit/tests/functions.php tests/phpunit/tests/functions.php
index 6a9e35c9bd6..e22eb7ed278 100644
--- tests/phpunit/tests/functions.php
+++ tests/phpunit/tests/functions.php
@@ -914,4 +914,141 @@ class Tests_Functions extends WP_UnitTestCase {
 		$unique_uuids = array_unique( $uuids );
 		$this->assertEquals( $uuids, $unique_uuids );
 	}
+
+	/**
+	 * @ticket 39550
+	 * @dataProvider _wp_check_filetype_and_ext_data
+	 */
+	function test_wp_check_filetype_and_ext( $file, $filename, $expected ) {
+		if ( ! extension_loaded( 'fileinfo' ) ) {
+			$this->markTestSkipped( 'The fileinfo PHP extension is not loaded.' );
+		}
+
+		$this->assertEquals( $expected, wp_check_filetype_and_ext( $file, $filename ) );
+	}
+
+	/**
+	 * @ticket 39550
+	 */
+	function test_wp_check_filetype_and_ext_with_filtered_svg() {
+		$file = DIR_TESTDATA . '/uploads/video-play.svg';
+		$filename = 'video-play.svg';
+
+		$expected = array(
+			'ext' => 'svg',
+			'type' => 'image/svg+xml',
+			'proper_filename' => false,
+		);
+
+		add_filter( 'upload_mimes', array( $this, '_filter_mime_types_svg' ) );
+		$this->assertEquals( $expected, wp_check_filetype_and_ext( $file, $filename ) );
+
+		// Cleanup.
+		remove_filter( 'upload_mimes', array( $this, '_test_add_mime_types_svg' ) );
+	}
+
+	/**
+	 * @ticket 39550
+	 */
+	function test_wp_check_filetype_and_ext_with_filtered_woff() {
+		$file = DIR_TESTDATA . '/uploads/dashicons.woff';
+		$filename = 'dashicons.woff';
+
+		$expected = array(
+			'ext' => 'woff',
+			'type' => 'application/font-woff',
+			'proper_filename' => false,
+		);
+
+		add_filter( 'upload_mimes', array( $this, '_filter_mime_types_woff' ) );
+		$this->assertEquals( $expected, wp_check_filetype_and_ext( $file, $filename ) );
+
+		// Cleanup.
+		remove_filter( 'upload_mimes', array( $this, '_test_add_mime_types_woff' ) );
+	}
+
+	public function _filter_mime_types_svg( $mimes ) {
+		$mimes['svg'] = 'image/svg+xml';
+		return $mimes;
+	}
+
+	public function _filter_mime_types_woff( $mimes ) {
+		$mimes['woff'] = 'application/font-woff';
+		return $mimes;
+	}
+
+	public function _wp_check_filetype_and_ext_data() {
+		return array(
+			// Standard image.
+			array(
+				DIR_TESTDATA . '/images/canola.jpg',
+				'canola.jpg',
+				array(
+					'ext' => 'jpg',
+					'type' => 'image/jpeg',
+					'proper_filename' => false,
+				),
+			),
+			// Image with wrong extension.
+			array(
+				DIR_TESTDATA . '/images/test-image-mime-jpg.png',
+				'test-image-mime-jpg.png',
+				array(
+					'ext' => 'jpg',
+					'type' => 'image/jpeg',
+					'proper_filename' => 'test-image-mime-jpg.jpg',
+				),
+			),
+			// Image without extension.
+			array(
+				DIR_TESTDATA . '/images/test-image-no-extension',
+				'test-image-no-extension',
+				array(
+					'ext' => false,
+					'type' => false,
+					'proper_filename' => false,
+				),
+			),
+			// Valid non-image file with an image extension.
+			array(
+				DIR_TESTDATA . '/formatting/big5.txt',
+				'big5.jpg',
+				array(
+					'ext' => 'jpg',
+					'type' => 'image/jpeg',
+					'proper_filename' => false,
+				),
+			),
+			// Standard non-image file.
+			array(
+				DIR_TESTDATA . '/formatting/big5.txt',
+				'big5.txt',
+				array(
+					'ext' => 'txt',
+					'type' => 'text/plain',
+					'proper_filename' => false,
+				),
+			),
+			// Non-image file with wrong sub-type.
+			array(
+				DIR_TESTDATA . '/uploads/pages-to-word.docx',
+				'pages-to-word.docx',
+				array(
+					'ext' => 'docx',
+					'type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+					'proper_filename' => false,
+				),
+			),
+			// Non-image file not allowed.
+			array(
+				DIR_TESTDATA . '/export/crazy-cdata.xml',
+				'crazy-cdata.xml',
+				array(
+					'ext' => false,
+					'type' => false,
+					'proper_filename' => false,
+				),
+			),
+		);
+	}
 }
