PHP bug when uploading Word or Excel files to WordPress

If you’re unable to upload docx or xlsx files to WordPress due to “Sorry, this file type is not permitted for security reasons”, it may be down to this PHP bug. The MIME type of the file is reported incorrectly.

The bug seems to apply to PHP 7.3 upwards, and is not currently fixed. Here’s a workaround you can drop into functions.php:

function fix_office_file_mimetype_bug( $compact, $file, $filename, $mimes ) {
  if (strpos($filename, '.docx') !== false) {
    $finfo     = finfo_open( FILEINFO_MIME_TYPE );
    $real_mime = finfo_file( $finfo, $file );
    finfo_close( $finfo );

    if ($real_mime == 'application/vnd.openxmlformats-officedocument.wordprocessingml.documentapplication/vnd.openxmlformats-officedocument.wordprocessingml.document') {
      $compact['ext'] = 'docx';
      $compact['type'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
      $compact['proper_filename'] = $filename;
    }
  }

  if (strpos($filename, '.xlsx') !== false) {
    $finfo     = finfo_open( FILEINFO_MIME_TYPE );
    $real_mime = finfo_file( $finfo, $file );
    finfo_close( $finfo );

    if ($real_mime == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheetapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
      $compact['ext'] = 'xlsx';
      $compact['type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
      $compact['proper_filename'] = $filename;
    }
  }

  return $compact;
}
add_filter( 'wp_check_filetype_and_ext', 'fix_office_file_mimetype_bug', 10, 4 );