Thavarith
Thavarith

Reputation: 287

How do detect if the selected image for upload is a valid image?

I'm implementing a script which to validate an image for upload using php. Actually, the php script is working well with gif, png, and jpg image file, but when i have one condition that:

  1. I took an image theFileName.bmp and renamed its extension to theFileName.jpg.
  2. Then I select the renamed one to upload.

I renamed the image file name manually on my computer and then I selected the file to upload.

The uploading process tooks around 2 or 3 seconds then nothing showed up (not even an error), only the default message from browser displayed:

The connection to localhost was interrupted.

How can I prevent the user from selecting an image file (and any other file for that matter) which is not an actual valid image?

Solutions here

Finally, I managed to come up with my own solutions. It's a bit long but at least it can get the work done! Hope it might help someone.

  1. It helps prevent from user upload not wanted mime-type
  2. Prevent from user uses text file and renamed its extension and so on.
  3. Prevent from user uses text file and changes its mime-type
  4. Prevent from the file is unreadale
  5. Prevent from the file contains error
  6. Prevent from upload not an http
  7. Prevent from the image file size width: 0, height: 0
  8. There are still more things to validate and check in order to make sure it's safe by this means.

    # CHECK & TRY READ IMAGE FILE
    function is_readable_image( $theTmpFileloc ){
        try {
            if ( !getimagesize( $theTmpFileloc ) ){
                # THE IMAGE IS UNREADABLE
                return false;
            }
            # THE IMAGE IS READABLE
            return true;
    
        }catch( Exception $e ){
            # THE IMAGE IS OTHER FILE
            return false;
        }
    }
    # READ AND RETURN AN ARRAY OF IMAGE SIZES
    function get_image_size( $theTmpFileloc ){
        $imageSizes = array();
        $tmpResults = getimagesize( $theTmpFileloc );
        $imageSizes['width']  = $tmpResults[0];
        $imageSizes['height'] = $tmpResults[1];
    
        # IF EITHER WIDTH OR HEIGHT = 0, RETURN FALSE
        if ( $tmpResults[0] == 0 || $tmpResults[1] == 0 ) {
            return false;
        }
    
        return $imageSizes;
    }
    # READ AND RETURN AN IMAGE ACTUAL MIMETYPE
    function get_image_mime( $theTmpFileloc ){
        $imageMime  = '';
        $tmpResults = getimagesize( $theTmpFileloc );
        $imageMime  = $tmpResults['mime'];
    
        return $imageMime;
    }
    
    # START OF PHP TO VALIDATE IMAGE FILE
    if ( isset($_FILES['postImage']) && !empty($_FILES['postImage']['name']) ) {
        $tmpFileLoc      = $_FILES['postImage']['tmp_name'];
        $array_file_type = array('image/gif', 'image/png', 'image/x-png', 'image/jpeg', 'image/pjpeg');
    
        if ( $_FILES['postImage']['error'] == 1 ) {
            # THE IMAGE FILE CONTAINS ERROR
            $resMessage['Error']        = true;
    
        }elseif ( !is_uploaded_file( $tmpFileLoc ) ) {
            # PREVENT FROM UPLOADING FROM EXTERNAL SOURCE NOT HTTP
            $resMessage['Error']        = true;
    
        }elseif ( !is_readable_image( $tmpFileLoc ) ) {
            # PREVENT FROM IMAGE IS INVALID OR OTHER MIMETYPE
            $resMessage['Error']        = true;
    
        }elseif ( !get_image_size( $tmpFileLoc ) ) {
            # PREVENT FROM IMAGE SIZE 0, 0 OR INVALID ACTUAL MIMETYPE
            $resMessage['Error']        = true;
    
        }elseif ( !in_array( get_image_mime( $tmpFileLoc ), $array_file_type) ) {
            # LEVEL 2 OF CHECKING AN IMAGE MIMETYPE
            $resMessage['Error']        = true;
    
        }else {
            # other checks with file extension, max_size, 
            # dir is_writable and so on then move to move_uploaded_file
        }   
    }
    

Upvotes: 0

Views: 2588

Answers (2)

Othman Abahossain
Othman Abahossain

Reputation: 81

To give more security to your php script you should Use getimagesize(). If it returns FALSE it is not an image. Try also to make sure that the file is not too small. In addition you can use GD library.

Sorry for delaying you. you should give us a good example next time LOL.

Upvotes: 2

Naveen Kumar
Naveen Kumar

Reputation: 4601

Try this code

<?php
if (isset($_FILES['photo']))
{
    $mimetype = mime_content_type($_FILES['photo']['tmp_name']);
    if(in_array($mimetype, array('image/jpeg', 'image/gif', 'image/png'))) {
      move_uploaded_file($_FILES['photo']['tmp_name'],
      '/images/' . $_FILES['photo']['name']);
      echo 'OK';
    } else {
         echo 'Not an image file!';
    }
}

Upvotes: 0

Related Questions