What is the safest way to identify that the upload file is an image?

Asked

Viewed 1,130 times

7

I’m making a system where I can receive an image upload.

To check on the server if the file type is image, I thought of this code:

if (strpos($upload->getClientMimeType(), 'image') !== 0) {

    throw new UploadException(
        sprintf('Extensão de arquivo %s é inválida', $upload->getClientOriginalExtension())
    );
}

That is, checking if the file mime starts with "image", to know if it is an image or not, since the mimes of images are usually image/png, image/jpeg, image/gif...

But I was wondering if this would really be safe, besides having own concern if there is some other image type file that does not have the mime prefixed by image.

I’d like to know:

  • The example demonstrated for image verification is sufficient to maintain upload security or not?

What are the best ways to check image uploads in PHP?

Note: I am currently using the framework , but I wouldn’t mind getting good suggestions using only pure php.

2 answers

7


In my view technically there is no problem in using mimetypes, in fact it is much more guaranteed with them than file extensions (thing that many people do unfortunately), something I explained here how to do only with PHP

The only problem I see is the lack of / after image in:

if (strpos($upload->getClientMimeType(), 'image') !== 0) {

What could allow entering a document that had a mimetype like this imagexyz/foobar, That’s not really a security breach, because I don’t really know if it can cause anything, since I don’t think there are any other mimetypes that start with image***/, under warranty make:

if (strpos($upload->getClientMimeType(), 'image/') !== 0) {

Of course this will allow you to climb:

  • icons (image/icon, image/x-icon, image/vnd.microsoft.icon)
  • svg (image/svg+xml)
  • Photoshop (image/vnd.adobe.photoshop)

Among others.

This is your choice, so if you want to limit to jpg, gif and png formats make use of in_array:

$formatospermitidos = array( 'image/jpeg', 'image/gif', 'image/png' );

if (!in_array($upload->getClientMimeType(), $formatospermitidos)) {
  • +1 of the hour your answer. I am only worried about the mime of AI (Abode Ilustrator), but there is another problem.

  • 1

    Yes, there are some programmers who use even file extensions to check upload, or put a validation in Javascript and think it’s good size (I was once one of them :p)

  • 1

    @Wallacemaxters I prefer to always limit with in_array.

  • But that’s what I’m going to have to do anyway. Why, in the specific case, I’m going to need to put pdf also. But this is off-topic, no need to modify your answer, since the context is only images.

  • 1

    And where is the guarantee of being safe? It’s like doing or is it safe @Wallacemaxters?

  • Please avoid long discussions in the comments; your talk was moved to the chat

Show 1 more comment

6

As already mentioned the best options for @Guilherme Nascimento, I’ll make an addendum to his reply:

In the PHP there is the function exif_imagetype in which it determines the type of the image through the signing in the first bytes file, analyzing more deeply, based on predefined constants, they are:

Value   Constant
1   IMAGETYPE_GIF
2   IMAGETYPE_JPEG
3   IMAGETYPE_PNG
4   IMAGETYPE_SWF
5   IMAGETYPE_PSD
6   IMAGETYPE_BMP
7   IMAGETYPE_TIFF_II (intel byte order)
8   IMAGETYPE_TIFF_MM (motorola byte order)
9   IMAGETYPE_JPC
10  IMAGETYPE_JP2
11  IMAGETYPE_JPX
12  IMAGETYPE_JB2
13  IMAGETYPE_SWC
14  IMAGETYPE_IFF
15  IMAGETYPE_WBMP
16  IMAGETYPE_XBM
17  IMAGETYPE_ICO

An example of its use:

if (exif_imagetype('image.gif') != IMAGETYPE_GIF) {
    echo 'O arquivo não é .gif';
}

PS¹: As recalled by William, the duties exif_* are usually not enabled by default.

PS²: Depending on how will be treated these images that are being loaded, I advise you to explicitly inform which types are supported not to occur of you being treating a simple image .gif and receive a .svg, for example.

  • 3

    The functions exif_* are rarely enabled by default (requires extension=exif.so, extension=php_exif.dll in windows), even more so in Shared hosting, I believe. It is still a good alternative.

  • Yeah, good to remember that.

  • +1.. I did not know this function. Thank you

  • 1

    @Guilhermenascimento my case hosting is Shared :\

Browser other questions tagged

You are not signed in. Login or sign up in order to post.