MIME Type spoofing

11,002

Solution 1

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.

Solution 2

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.

Share:
11,002

Related videos on Youtube

abruski
Author by

abruski

Studies Astrophysics @ Sofia University, Bulgaria

Updated on June 04, 2022

Comments

  • abruski
    abruski almost 2 years

    Checking for mime type in php is pretty easy but as far as I know mime can be spoofed. The attacker can upload a php script with for example jpeg mime type. One thing that comes to mind is to check the file extension of the uploaded file and make sure it matches the mime type. All of this is assuming the upload directory is browser accessible.

    Question: Are there any other techniques for preventing "bad files" from getting in with mime type spoofing?

    • CodeCaster
      CodeCaster over 12 years
      Is your question about mime type spoofing, or do you just want to know how to validate uploaded files to check if they're image files?
    • Damien Pirsy
      Damien Pirsy over 12 years
      In fact, you shouldn't rely on MIME types and file extension in the first place (and your check, if mime->extension, is also wrong; if I fake mime I can fake even more easily a corresponding file xtension)
  • abruski
    abruski over 12 years
    It does not have to be an image, it can be any kind of file.
  • abruski
    abruski over 12 years
    The images were only examples. Would be dealing with PDF files. But I wanted to generalize the question so it would help with other file types too
  • stivlo
    stivlo over 12 years
    I see, let me expand the answer then.
  • emboss
    emboss over 12 years
    The principle is always the same. A smart attacker gives you what you expect, but crafts the file in a way that it exploits the most popular libraries used to view the files. For PDF that would mean that they might embed Javascript, videos, again images... the number of options increases drastically with the features provided by the data format. If you (or your clients!) never "execute" (viewing is "executing", too) uploaded content, only then you are safe.
  • Pekka
    Pekka over 12 years
    It's possible to get a "safe" image by copying it over into a new image using a library like GD or a tool like ImageMagick. AFAIK, there is no known open exploit for any of these libraries - there used to be one in Windows' GDI but that has been fixed long since. While it's true that in theory, there is no safety, there are ways to deal with files in a safe manner.
  • Marshall Mathews
    Marshall Mathews about 12 years
    thats great if getimagesize returns false if its not an image :-) very useful for checking id guess but what if extension is spoofed and mime type too?
  • chintogtokh
    chintogtokh over 5 years
    The documentation for getimagesize explicitly states "Do not use getimagesize() to check that a given file is a valid image. Use a purpose-built solution such as the Fileinfo extension instead."
  • stivlo
    stivlo over 5 years
    thanks for pointing it out - I've added a warning on top of the answer -- the documentation didn't say that in 2011 -- see errors/exceptions web.archive.org/web/20111224150939/http://php.net/manual/en/‌​…