DOCX File type in PHP finfo_file is application/zip

Viewed 18798

hello I'm trying to validate an uploaded file type by finfo_file function.

But when a .docx file is sent, the file type is:

application/zip

instead of:

application/vnd.openxmlformats-officedocument.wordprocessingml.document

how can I change this behavior?

7 Answers

See my answer in this thread:

Overview

PHP uses libmagic. When Magic detects the MIME type as "application/zip" instead of "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", this is because the files added to the ZIP archive need to be in a certain order.

This causes a problem when uploading files to services that enforce matching file extension and MIME type. For example, Mediawiki-based wikis (written using PHP) are blocking certain XLSX files from being uploaded because they are detected as ZIP files.

What you need to do is fix your XLSX by reordering the files written to the ZIP archive so that Magic can detect the MIME type properly.

...

The post continues to analyze the file and develop a solution by rewriting the file.

Here is the file list for a DOCX file created using Word.

$ unzip -l Word.docx
Archive:  Word.docx
  Length      Date    Time    Name
---------  ---------- -----   ----
     1364  1980-01-01 00:00   [Content_Types].xml
      734  1980-01-01 00:00   _rels/.rels
      817  1980-01-01 00:00   word/_rels/document.xml.rels
     1823  1980-01-01 00:00   word/document.xml
     6799  1980-01-01 00:00   word/theme/theme1.xml
     2068  1980-01-01 00:00   docProps/thumbnail.emf
     2652  1980-01-01 00:00   word/settings.xml
     1954  1980-01-01 00:00   word/fontTable.xml
      576  1980-01-01 00:00   word/webSettings.xml
      735  1980-01-01 00:00   docProps/core.xml
    28979  1980-01-01 00:00   word/styles.xml
      709  1980-01-01 00:00   docProps/app.xml
---------                     -------
    49210                     12 files

You may have to imitate that file order or try writing the "[Content_Types].xml", "word/document.xml", and "word/styles.xml" files first before other files.

We had the same problem with PHP 5.3. It works fine under PHP 7.2. I have application/vnd.openxmlformats-officedocument.wordprocessingml.document for my docx file.

To ensure that you have a docx file under PHP 5.3, you check the mime type from the [Content_Types].xml file in the archive (docx).

PHP 7.3 can now detect it properly using finfo_file(). The fileinfo PHP extension uses bundled libmagic and seems the library already detects .docx files correctly in all currently supported PHP versions (7.4, 8.0, 8.1).

Running

finfo_file(finfo_open(FILEINFO_MIME_TYPE), 'test.docx');

now returns

application/vnd.openxmlformats-officedocument.wordprocessingml.document

You can see the result of the same function call on older PHP versions here https://3v4l.org/uSqkR - notice the change on 7.3. The example is using finfo_buffer() and Base64-encoded file so that I can have the file "inlined" in the PHP code.

If the correct type is not detected, it's possible you may be using (even unknowingly) a custom "magic" database which does not support the type. You can specify the database as an extra parameter to finfo_open(), for example

finfo_open(FILEINFO_MIME_TYPE, '/etc/magic.mime');

If the code you're using is doing that, and you're using PHP 7.3 or newer, remove the /etc/magic.mime parameter.

The database can also be specified using the MAGIC environment variable, check you have it unset with for example getenv('MAGIC') or in phpinfo() output. If that's the case you can remove the variable wherever is set, or unset it in your PHP code (putenv('MAGIC')) before using finfo_open():

putenv('MAGIC');
finfo_file(finfo_open(FILEINFO_MIME_TYPE), 'test.docx');
Related