Проверка mime type php

MIME type detection for PHP file uploads

This weekend was my website offline for 3 hours because my hosting provider has detected a malicious file inside the upload directory I use for some PHP upload demo on my website. This breach was (also) possible because I forgot several month ago to update a CRON job that deletes all upload files frequently. The downtime takes 3 hours because it was in the middle of the night based in the timezone where I live. After I removed that malicious file, my web hosting provider Webfaction enabled my website within just a few minutes.

MIME type detection during uploads

How was it possible that someone was able to upload a malicious file? My PHP upload demo is using the PHP upload class I have written several years ago. This “old” PHP class is a script that I’m still using for many custom scripts and websites. MIME type detection was available for version 2.33 which was released more than two years, but it seems my demo wasn’t using that feature. The validation for the file extension worked fine and the malicious file was a JPG file.

The old MIME type detection was based on the PHP function mime_content_type() which is marked as depreciated since a while. In the latest version of my upload script, the complete MIME type function is rewritten and supports now the Fileinfo extension for PHP 5. The new class method get_mime_type() still supports the old function mime_content_type() as a kind of fallback for older scripts.

function get_mime_type($file) < $mtype = false; if (function_exists('finfo_open')) < $finfo = finfo_open(FILEINFO_MIME_TYPE); $mtype = finfo_file($finfo, $file); finfo_close($finfo); >elseif (function_exists('mime_content_type')) < $mtype = mime_content_type($file); >return $mtype; >

Check MIME type is always ON now

In the previous version it was necessary to enable the MIME type detection during upload and that was also the reason why my upload demo failed. You need to set the new variable $validate_mime to “false” if your web host doesn’t support one of the MIME type detection functions. The Fileinfo extension is enabled by default since PHP version 5.3 and should be available on most web hosts.

Other updates for PHP Upload Class 2.34

Beside the new method, I have updated the way how the file’s MIME type is checked during upload. While testing I noticed that the old REGEX pattern, which is used to validate a “valid” file name, has some bugs. The pattern is updated and should work for all regular file names now. Furthermore got the class script some code clean-up. The updated PHP class should work for older upload scripts which are created with the class version 2.x. Try the updated PHP Upload demo or download the updated version here.

About Webfaction – Hosting for developers
A secure web host is important for the success of your website. Webfaction is a shared hosting provider that cares about your website. Curious about features and price? Check their website or better sign-up for a 30 days trial (no credit card required).

PHP download file script This is my favorite PHP download script. Before I’ve used a different more simple method,…

Читайте также:  Абстрактные классы python примеры

jQuery form plugin and PHP file uploads The past months I used the jQuery form plugin in several projects. Most forms were…

Ajax file upload PHP / jQuery Tutorial The asynchronous file upload, using some XMLHttpRequest (Ajax), is technically not possible. Most JavaScript examples…

5 Comments

Update to version 2.35 released! In the previous version of the PHP upload class the check for (HTTP) upload errors was a kind of mess. There wasn’t really a check for this error and the message was reported in a later state of the upload process. The script worked good until it comes to those errors. This problem is fixed and you can download the new version from this website.

I have been working with your scripts to see if I can get them to upload files to my daughter’s site at breakfrast.com. I keep getting the following error: “The file type (MIME type) is not valid.
You have tried to upload 1 files with a bad extension, the following extensions are allowed: .bmp .gif .jpg .jpeg .png” I am uploading a small .jpg that I tried at your example on your site that worked. I am running solaris 10 with php 5.2. Also, any chance you have this same script working with imageMagick convert? I have been unsuccessfully trying to upload with ImageMagick script and have decided to go back and do uploads first, then add in the convert portion. Thanks.

Hi Irwin, The Fileinfo extension is enabled by default since PHP version 5.3 and since you’re using a very old PHP version (5.2) it’s possible that the extension is not enabled. Do you checked that first? You can check that with the function phpinfo(). If the extension is enabled, you will find some info like: fileinfo support enabled, version 1.0.5 You can the variable $validate_mime to “false” if the fileinfo extension is disabled.

I found the foto files with the additional class and modified those to the site. When I change $validate_mime = false I still get the same message. Even though I have confirmed I have PECL / Pear installed and enabled I can’t figure out how to enable the mime module. I have mime modules enabled on Apache. Any ideas?

Please try the “standard” class first, I’m not sure that I did all tests for the photo class extensions after the last update.
Note, mime modules for Apache are not related to the PHP fileInfo extension or mime_content_type() functions used in the class. If the installation of this extension is a problem, I suggest to update PHP to the latest version. Please don’t post a link to your website if the site isn’t available. My broken link checker doesn’t like that 😉

Читайте также:  Python keyerror print key

Источник

mime_content_type

Возвращает MIME-тип содержимого файла, используя для определения информацию из файла magic.mime .

Список параметров

Путь к проверяемому файлу.

Возвращаемые значения

Возвращает тип содержимого в формате MIME, например text/plain или application/octet-stream или false в случае возникновения ошибки.

Ошибки

В случае неудачного завершения работы генерируется ошибка уровня E_WARNING .

Примеры

Пример #1 Пример mime_content_type()

Результат выполнения данного примера:

Смотрите также

User Contributed Notes 21 notes

Fast generation of uptodate mime types:

echo
generateUpToDateMimeArray ( APACHE_MIME_TYPES_URL );
?>

Output:
$mime_types = array(
‘123’ => ‘application/vnd.lotus-1-2-3’,
‘3dml’ => ‘text/vnd.in3d.3dml’,
‘3g2’ => ‘video/3gpp2’,
‘3gp’ => ‘video/3gpp’,
‘7z’ => ‘application/x-7z-compressed’,
‘aab’ => ‘application/x-authorware-bin’,
‘aac’ => ‘audio/x-aac’,
‘aam’ => ‘application/x-authorware-map’,
‘aas’ => ‘application/x-authorware-seg’,
.

There is a composer package that will do this:
https://github.com/ralouphie/mimey

$mimes = new \ Mimey \ MimeTypes ;

// Convert extension to MIME type:
$mimes -> getMimeType ( ‘json’ ); // application/json

// Convert MIME type to extension:
$mimes -> getExtension ( ‘application/json’ ); // json

and string detection on text files may fail if you check a file encoded with signed UTF-8. The UTF-8 signature is a two bytes code (0xFF 0xFE) that prepends the file in order to force UTF-8 recognition (you may check it on an hexadecimal editor).

For me mime_content_type didn’t work in Linux before I added

to php.ini (remember to find the correct path to mime.magic)

using
function detectFileMimeType ( $filename = » )
$filename = escapeshellcmd ( $filename );
$command = «file -b —mime-type -m /usr/share/misc/magic < $filename >» ;

$mimeType = shell_exec ( $command );

return trim ( $mimeType );
>
?>
should work on most shared linux hosts without errors. It should also work on Windows hosts with msysgit installed.

Lukas V is IMO missing some point. The MIME type of a file may not be corresponding to the file suffix.

Imagine someone would obfuscate some PHP code in a .gif file, the file suffix would be ‘GIF’ but the MIME would be text/plain or even text/html.

Another example is files fetched via a distant server (wget / fopen / file / fsockopen. ). The server can issue an error, i.e. 404 Not Found, wich again is text/html, whatever you save the file to (download_archive.rar).

His provided function should begin by the test of the function existancy like :

function MIMEalternative($file)
if(function_exists(‘mime_content_type’))
return mime_content_type($file);
else
return ($file);
>

I see a lot of comments suggesting doing file extension sniffing (i.e. assuming .jpg files are JPEG images) when proper file-type sniffing functions are unavailable.
I want to point out that there is a much more accurate way.
If neither mime_content_type() nor Fileinfo is available to you and you are running *any* UNIX variant since the 70s, including Mac OS, OS X, Linux, etc. (and most web hosting is), just make a system call to ‘file(1)’.
Doing something like this:
echo system ( «file -bi »» );
?>
will output something like «text/html; charset=us-ascii». Some systems won’t add the charset bit, but strip it off just in case.
The ‘-bi’ bit is important. However, you can use a command like this:
echo system ( «file -b »» ); // without the ‘i’ after ‘-b’
?>
to output a human-readable string, like «HTML document text», which can sometimes be useful.
The only drawback is that your scripts will not work on Windows, but is this such a problem? Just about all web hosts use a UNIX.
It is a far better way than just examining the file extension.

Читайте также:  Html запрет горизонтальной прокрутки

Here’s a simple function to return MIME types, based on the Apache mime.types file. [The one in my previous submission, which has since been replaced by this one] only works properly if mime.types is formatted as Windows text. The updated version below corrects this problem. Thanks to Mike for pointing this out.

function get_mime_type ( $filename , $mimePath = ‘../etc’ ) <
$fileext = substr ( strrchr ( $filename , ‘.’ ), 1 );
if (empty( $fileext )) return ( false );
$regex = «/^([\w\+\-\.\/]+)\s+(\w+\s)*( $fileext \s)/i» ;
$lines = file ( » $mimePath /mime.types» );
foreach( $lines as $line ) <
if ( substr ( $line , 0 , 1 ) == ‘#’ ) continue; // skip comments
$line = rtrim ( $line ) . » » ;
if (! preg_match ( $regex , $line , $matches )) continue; // no match to the extension
return ( $matches [ 1 ]);
>
return ( false ); // no match at all
>
?>

Notes:
[1] Requires mime.types file distributed with Apache (normally found at ServerRoot/conf/mime.types). If you are using shared hosting, download the file with the Apache distro and then upload it to a directory on your web server that php has access to.

[2] First param is the filename (required). Second parameter is path to mime.types file (optional; defaults to home/etc/). [3] Based on MIME types registered with IANA (http://www.iana.org/assignments/media-types/index.html). Recognizes 630 extensions associated with 498 MIME types. [4] Asserts MIME type based on filename extension. Does not examine the actual file; the file does not even have to exist. [5] Examples of use:
>> echo get_mime_type(‘myFile.xml’);
>> application/xml
>> echo get_mime_type(‘myPath/myFile.js’);
>> application/javascript
>> echo get_mime_type(‘myPresentation.ppt’);
>> application/vnd.ms-powerpoint
>> echo get_mime_type(‘http://mySite.com/myPage.php);
>> application/x-httpd-php
>> echo get_mime_type(‘myPicture.jpg’);
>> image/jpeg
>> echo get_mime_type(‘myMusic.mp3’);
>> audio/mpeg
and so on.

To create an associative array containing MIME types, use:
function get_mime_array ( $mimePath = ‘../etc’ )
<
$regex = «/([\w\+\-\.\/]+)\t+([\w\s]+)/i» ;
$lines = file ( » $mimePath /mime.types» , FILE_IGNORE_NEW_LINES );
foreach( $lines as $line ) <
if ( substr ( $line , 0 , 1 ) == ‘#’ ) continue; // skip comments
if (! preg_match ( $regex , $line , $matches )) continue; // skip mime types w/o any extensions
$mime = $matches [ 1 ];
$extensions = explode ( » » , $matches [ 2 ]);
foreach( $extensions as $ext ) $mimeArray [ trim ( $ext )] = $mime ;
>
return ( $mimeArray );
>
?>

Источник

Оцените статью