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:
- I took an image
theFileName.bmp
and renamed its extension totheFileName.jpg
. - 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.
- It helps prevent from user upload not wanted mime-type
- Prevent from user uses text file and renamed its extension and so on.
- Prevent from user uses text file and changes its mime-type
- Prevent from the file is unreadale
- Prevent from the file contains error
- Prevent from upload not an http
- Prevent from the image file size width: 0, height: 0
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 } }