0

I am in the process of writing an image upload script. I am adding lots of things e.g. store outside webroot and access through php script etc. One thing I have read to check is that a file is uploaded instead of an image. E.g. stop myimage.php.jpeg

I have written the following code to check it is an image file. Is this the best way to check this file has an image name?

$imagename= $_FILES['myimage']['name'];

//check there is only one fullstop in the imagename
 if (substr_count($imagename,".")===1){
    $imagesuffix = substr($imagename, strpos($imagename, ".") + 1); 

    //if image type is not a particular type of image
      if($imagesuffix != "jpg"|| $imagesuffix != "png"||$imagesuffix != "jpeg"||$imagesuffix != "gif"){
       echo"image filename is valid";
     }
     else{
       echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
     }
 }
 else{
    echo"this filename is invalid";
 }
bevan77
  • 1
  • 1
  • `foo.bar.jpg` is a perfectly valid file name. Why are you rejecting it? – ceejayoz Dec 04 '18 at 22:29
  • I want to stop mypretendimage.php.jpg – bevan77 Dec 04 '18 at 22:30
  • This code [won't stop someone](https://phocean.net/2013/09/29/file-upload-vulnerabilities-appending-php-code-to-an-image.html) from uploading a malicious file containing PHP. Instead, you should [disable PHP execution within your uploads directory](https://stackoverflow.com/questions/1271899/disable-php-in-directory-including-all-sub-directories-with-htaccess). The PHP docs recommend using [Fileinfo](http://php.net/manual/en/function.finfo-file.php) to check if it's an image. – ceejayoz Dec 04 '18 at 22:34
  • 1
    Please do not base your code decisions on filename extensions. There's so many reasons not to. The easiest one: not all operating systems require extensions so uploaded files could end up not having any. The dirtiest one: I could create a malicious program and rename it `supercoolimage.jpg` and you wouldn't even know the difference... Not something you want happening – Javier Larroulet Dec 04 '18 at 22:46

1 Answers1

0

If your concern is to only allow uploads of files that are images, then you'll have to look at the file contents.

    <?php

    $image = 'image_file_to_test.png';

    if (($imageInfo = getimagesize($image, $jpegInfo)) === FALSE)
            die('Not an image.');
// OR    

    if (($imageType = exif_imagetype($image)) === FALSE)
            die('Not an image');

If so desired, you can inspect either $imageInfo (docs) or $imageType (docs) to determine the image format. Please note that exif_imagetype() is the faster of the two, but it won't tell you as much as getimagesize().

Ro Achterberg
  • 2,504
  • 2
  • 17
  • 17
  • 1
    I'd note the `getimagesize` docs explicitly state you *shouldn't* use them for this. "Do not use getimagesize() to check that a given file is a valid image. Use a purpose-built solution such as the Fileinfo extension instead." – ceejayoz Dec 05 '18 at 14:35