GetImageSize() not returning FALSE when it should

情到浓时终转凉″ 提交于 2019-11-26 18:30:29

问题


Working on a little upload script here. I'm trying to check if the uploaded image really is an image and not just a renamed PHP file.

When the script is posted I can print the array with

foreach ($_FILES['images']['name'] as $key => $value){             
        print_r(getimagesize($_FILES['images']['tmp_name'][$key]));

That works just fine, so it won't return false. But even if I upload a file that is not an image, it won't give false. It just returns nothing at all, and the rest of my script just processes the thing like an image.

Could anyone tell me what I am doing wrong?


回答1:


Upload

you can not use getimagesize on $_FILES['images']['tmp_name'][$key] directly .. you need to copy it into your system first before you can use it

Use $_FILES['images']['size'][$key] temporarily

Or

  move_uploaded_file($_FILES['images']['tmp_name'][$key], $destination);
  print_r(getimagesize($destination));

Fake Image

Please not that $_FILES['images']['type'][$key] can be faked

Using Fake image Headers

Example

file_put_contents("fake.png", base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABGdBTUEAALGPC/xhBQAAAAZQTFRF////
AAAAVcLTfgAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH0gQCEx05cq
KA8gAAAApJREFUeJxjYAAAAAIAAUivpHEAAAAASUVORK5CYII='));

Uploading fake.png

array
  'name' => 
    array
      0 => string 'fake.png' (length=8)
  'type' => 
    array
      0 => string 'image/png' (length=9)
  'tmp_name' => 
    array
      0 => string 'C:\Apache\xampp\tmp\php44F.tmp' (length=30)
  'error' => 
    array
      0 => int 0
  'size' => 
    array
      0 => int 167

Validate Image

Usage

var_dump ( getimagesizeReal ( "fake.png" ) );

Function Used

function getimagesizeReal($image) {

    $imageTypes = array (
            IMAGETYPE_GIF,
            IMAGETYPE_JPEG,
            IMAGETYPE_PNG,
            IMAGETYPE_SWF,
            IMAGETYPE_PSD,
            IMAGETYPE_BMP,
            IMAGETYPE_TIFF_II,
            IMAGETYPE_TIFF_MM,
            IMAGETYPE_JPC,
            IMAGETYPE_JP2,
            IMAGETYPE_JPX,
            IMAGETYPE_JB2,
            IMAGETYPE_SWC,
            IMAGETYPE_IFF,
            IMAGETYPE_WBMP,
            IMAGETYPE_XBM,
            IMAGETYPE_ICO 
    );
    $info = getimagesize ( $image );
    $width = @$info [0];
    $height = @$info [1];
    $type = @$info [2];
    $attr = @$info [3];
    $bits = @$info ['bits'];
    $channels = @$info ['channels'];
    $mime = @$info ['mime'];

    if (! in_array ( $type, $imageTypes )) {
        return false; // Invalid Image Type ;
    }
    if ($width <= 1 && $height <= 1) {
        return false; // Invalid Image Size ;
    }

    if($bits === 1)
    {
        return false; // One Bit Image .. You don't want that  ;
    }
    return $info ;
}



回答2:


I'd like to recommend against trusting the results of getimagesize() when deciding whether to place the uploaded file anywhere in your document root. That's because PHP code embedded in GIF files (titled like image.gif.php) will be identified as images by getimagesize(), but serving them will run the PHP code inside them in addition to displaying the image. Here is some more information on the issue.

The article linked above recommends setting up a separate controller through which all the user uploaded files are served. Files read with readfile() are not parsed when accessed through the local filesystem.




回答3:


Firstly, you can use getimagesize on $_FILES['images']['tmp_name'], so that's not an issue.

If you want to check if the file is an image, then try this:

if(isset($_POST['submit'])) {
    $check = getimagesize($_FILES['images']['tmp_name']);
    if($check !== false) {
        echo 'File is an image - ' . $check['mime'];
    }
    else {
        echo 'File is not an image';
    }
}



回答4:


You can simply use $_FILES['images']['type'] . it'll give you the type of file uploaded. Then check it againt octate stream or other executable file. If so then do not allow it.




回答5:


@user1362916 If you are uploading multiple images with HTML then perhaps you need to add one more array like this.

if(isset($_POST['submit'])) {
    $check = getimagesize($_FILES['images']['tmp_name'][$i]);
    if($check !== false) {
        echo 'File is an image - ' . $check['mime'];
    }
    else {
        echo 'File is not an image';
    }
}

Here check [i] because this is for multiple file upload.

Below is full script

<!DOCTYPE html>
<html>
<body>

<form action="#" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input name="my_files[]" type="file" multiple="multiple" />
    <input type="submit" value="Upload Image" name="submit">
</form>


<?php

 if (isset($_FILES['my_files']))
 {
    $myFile = $_FILES['my_files'];
    $fileCount = count($myFile["name"]);


        for ($i = 0; $i <$fileCount; $i++)
         {
           $error = $myFile["error"][$i]; 

            if ($error == '4')  // error 4 is for "no file selected"
             {
               echo "no file selected";
             }
            else
             {
               if(isset($_POST['submit'])) {
                 $check = getimagesize($_FILES['my_files']['tmp_name'][$i]);
                 if($check !== false) {
                 echo 'File is an image - ' . $check['mime'];
                 }
                 else {
                 echo 'File is not an image';
                   }
                 }

             }
       }  
 }
        ?>


</body>
</html>


来源:https://stackoverflow.com/questions/10464948/getimagesize-not-returning-false-when-it-should

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!