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).

Published in: PHP Scripts

5 Comments

  1. 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.

  2. 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.

    1. 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.

  3. 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?

    1. 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 ;)

Comments are closed.