Files filtering

I am trying to get this if statement regarding the file type and file size to work. Since I upload multiple files (jpeg only), I want to make sure that all the files are of a .jpg or .jpeg file extension, nothing else

if ($error == UPLOAD_ERR_OK){
        $tmp_name_array = $_FILES['file_array']['tmp_name'][$item];
        $name_array = $_FILES['file_array']['name'][$item];
        $type_array = $_FILES['file_array']['type'][$item];
        $size_array = $_FILES['file_array']['size'][$item];
    if (!in_array($type_array, array('image/jpeg'))){
        echo "Invalid file type, must only be Jpeg, no other format are accepted";
        exit();
    }
if (in_array($size_array, array('size') > 204800)){
    echo "One or more file(s) are too large, please upload a smaller file(s)";
    exit();
}

When I put in a different type of file, to make sure this is working correctly, the error message doesn’t display. Since I don’t want the rest of the other IF statement to run, I have put exit();

How can this be corrected in order for the error message to be displayed?

Not tested and off the top of my head and just for food for thought (and assuming you are sending back an array of files, which I am not sure you are doing).

if ($error == UPLOAD_ERR_OK){
    if( ! isJpeg($_FILES['files_array'])){
        echo "Invalid file type, must only be Jpeg, no other format are accepted";
        //exit();
    }
}
 ......// the rest of your code

function isJpeg($files)
{    
     foreach($files as $file){
         if($file['type'] !== 'image/jpeg'){
             return false;
         }
     }
     return true;
}

Scott

OK, so the if statement really does seem to be working, just it doesn’t work with some file extensions, but the file size doesn’t seem to be working

Keeps saying that I need two parameters and that I’ve only got one

there is a nice example for image uploads not relying on the passed type in the Manual: http://php.net/manual/en/features.file-upload.php#114004

1 Like

Found the problem, didn’t need the

in_array() 

function

I’ve been saying this a lot, but don’t check for file extensions. Someone can create a file called image.php.jpg. The file indeed does end with .jpg, however, this file could be an executable php file masked to cause havoc. This is very popular amongst amateur PHP users. If you want to keep using what you are using now, by all means. Go for it. However I would like to recommend checking for fileinfo.

With fileinfo, you can check the file to make sure it has the actual right image bytes. If it doesn’t, the file extension has been changed.

Let’s say you create a file called image.txt. You write a bunch of malicious codes in the image.txt file, you use something like FileZilla to change the .txt to .jpg. You upload it to your live server and it accepts it. This means your whole entire server has been compromised. The file indeed will be image.jpg. However the mime type is text/plain (which is the proper mime type for a .txt file). Image files normally have a mime type of image/jpeg, image/gif, image/png, .etc. So checking for just a .jpg extension is no longer valid anymore. You are passing a text file as an image file.

You can actually try this method with Facebook. Create a random file that has random stuff in it. Change the file extension to .jpg. Try uploading it on Facebook as Photo/ Video. It’ll reject it. Why? Because fileinfo. Fileinfo doesn’t check for .jpg because the extension is irrelevant at this point.

That is good to know spaceshiptrooper. Thanks for the info. However, he is checking for the mime type. Or did you just throw that in for good measure? :smiley:

Scott

Nice point, but how would I go about coding this into the script that I have already available?

For images it is better to check that it is actually an image file rather than checking the MIME type.

And how can you do that?

Scott

Probably the simplest test to start would be:

$size = getimagesize($filename);
if ($size && $size['mime'] == 'image/jpeg')
   echo 'a jpeg image';

which has the advantage over simply testing the mime type in that it first checks that it is actually an image.

So a text file that is passed with an image mime type would fail the test for being an image even if it has the correct mime type.

1 Like

I didn’t see his mime type checking. I just read the part where he wanted to check for file extensions which is bad as I said in my post.

I think you already have mime type checking.

Here’s a nice article. http://stackoverflow.com/questions/28661224/getimagesize-vs-finfo-file-the-exact-same-for-detecting-mime-type

Each person prefers something slightly different. I prefer checking for mime type and header bytes. I’ve seen a lot of posts saying that mime type can be spoofed. That is just people posting what others have said. Until the day I actually see a live or recorded demonstration that myth busts file info and mime type checking, I’ll keep telling others to check for mime type as checking for file extensions are no longer valid.

Also, you are still checking for mime type even with getimagesize. It makes no difference what you want to use.

It makes a difference where the file isn’t actually an image but has been given an image MIME type - which is a security hole that has been known to have been exploited in the past - particularly since there are some image types that allow text to be legitimately stored either before or after the image content itself (eg the info about where the photo was taken and when)

Plus you only need to test the MIME type if you only want to accept some image formats - if you simply need want to limit it to images of any type then testing if it actually is an image is sufficient without worrying about the MIME type.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.