MIME Type spoofing

Short answer: No.

Longer answer:

Comparing the extension and making sure that it matches the MIME type doesn't really prevent anything. As was said in the comments, it's even easier to modify a file extension. MIME type and extension are only to be meant as hints, there's no inherent security in them.

Ensuring that incoming files do no harm is very dependent on what your purpose for them is going to be. In your case I understood that you are expecting images. So what you could do is perform some sanity checks first: scan the first couple of bytes to see if the files contain the relevant image header signatures - all relevant image formats have these.

The "signature headers" help you to decide what kind of image format a file tries to impersonate. In a next step you could check if the rest of the contents are compliant with the underlying image format. This would guarantee you that the file is really an image file of that specific format.

But even then, the file could be carefully crafted in a way that when you display the image, a popular library used to display that image (e.g. libpng etc.) would run into a buffer overflow that the attacker found in that library.

Unfortuantely there's no way to actively prevent this besides not allowing any input from the client side at all.


Caution - this answer is now obsolete

The documentation for getimagesize explicitly states "Do not use getimagesize() to check that a given file is a valid image.

In case of Images

  • Check the extension with a list of allowed ones (ex. ".jpg", ".jpeg", ".png")
  • Check the uploaded file itself by running getimagesize on the file, it will return FALSE if it's not an image.

Other types of upload

  • Check the allowed extensions (ex. ".pdf")
  • Check that the mime type of the file corresponds to the extension

Sample code:

function getRealMimeType($filename) {
    $finfo = new finfo(FILEINFO_MIME, "/usr/share/misc/magic"); 
    if (!$finfo) {
        echo "Opening fileinfo database failed";
        return "";
    }
    return $finfo->file($filename);
}

See finfo_file documentation.