PHP Uploading files - image only checking

41,375

Solution 1

Yes, quite easily. But first off, you need some extra bits:

// never assume the upload succeeded
if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
   die("Upload failed with error code " . $_FILES['file']['error']);
}

$info = getimagesize($_FILES['file']['tmp_name']);
if ($info === FALSE) {
   die("Unable to determine image type of uploaded file");
}

if (($info[2] !== IMAGETYPE_GIF) && ($info[2] !== IMAGETYPE_JPEG) && ($info[2] !== IMAGETYPE_PNG)) {
   die("Not a gif/jpeg/png");
}

Relevant docs: file upload errors, getimagesize and image constants.

Solution 2

File path isn't necessarily the best way to check if an image really is an image. I could take a malicious javascript file, rename it to have the .jpg extension, and upload it. Now when you try to display it in your website, I may have just compromised your site.

Here is a function to validate it really is an image:

<?php
  function isImage($img){
      return (bool)getimagesize($img);
  }
?>

Solution 3

try this:

<?php

function isimage(){
$type=$_FILES['my-image']['type'];     

$extensions=array('image/jpg','image/jpe','image/jpeg','image/jfif','image/png','image/bmp','image/dib','image/gif');
    if(in_array($type, $extensions)){
        return true;
    }
    else
    {
        return false;
    }
}

    if(isimage()){
        //do codes..
    }

?>
Share:
41,375
TheBlackBenzKid
Author by

TheBlackBenzKid

Ecommerce specialist with 15+ years of experience in development, design, marketing and management. Application Acceleration CDN, Load balancing and performance NodeJS, Vanilla JS, AngularJS IBM WebSphere Commerce Fast Fashion advocate - love ecommerce, love luxury fashion Oracle ATG Web Commerce OPENCART Stack: NodeJS, PHP, NGINX, Smarty or a JS view framework Omni channel and mutli channel advocate PHP/MySQL/HTML5/CSS3/JavaScript/Nginx/Rackspace/AWS/jQuery/SaSS also GULP over WebPack (some fanboy love for ya!) oh.. and DEFO FLASH and GIF! As Gif and Flash will always come back with a boom! 2018 Big fan of Blockchain, Cryptography, Hash graph and block chain development

Updated on November 18, 2020

Comments

  • TheBlackBenzKid
    TheBlackBenzKid over 3 years

    I have a simple PHP upload script I have started. I am not the best to PHP. Just looking for some suggestions.

    I want to limit my script to only .JPG, .JPEG, .GIF and .PNG

    Is this possible?

    <?php
    /*
        Temp Uploader
    */
    
        # vars
        $mx=rand();
        $advid=$_REQUEST["advid"];
        $hash=md5(rand);
    
        # create our temp dir
        mkdir("./uploads/tempads/".$advid."/".$mx."/".$hash."/", 0777, true);
    
        # upload dir
        $uploaddir = './uploads/tempads/'.$advid.'/'.$mx.'/'.$hash.'/';
        $file = $uploaddir . basename($_FILES['file']['name']);
    
        // I was thinking of a large IF STATEMENT HERE ..
    
        # upload the file
        if (move_uploaded_file($_FILES['file']['tmp_name'], $file)) {
          $result = 1;
        } else {
          $result = 0;
        }
    
        sleep(10);
        echo $result;
    
    ?>
    
  • Surreal Dreams
    Surreal Dreams about 12 years
    Beat me to it - this method makes sure the file is an image, not just named like an image.
  • Marc B
    Marc B about 12 years
    You're assuming the remote user is not malicious and won't just rename nastyvirus.exe to cutekittens.jpg.
  • Mr Griever
    Mr Griever about 12 years
    The only caveat is that GD is not oob for PHP and can be finicky. finfo_file is standard in PHP after version 5.3.0 and will do a content-based check as well.
  • TheBlackBenzKid
    TheBlackBenzKid about 12 years
    How can I check the file resolution too? IE Size if width and height??
  • Marc B
    Marc B about 12 years
    A gif is a gif. They all share the same magic numbers at the start of the file.
  • Jessica
    Jessica over 8 years
    At the last if-statement, shouldn't it be || instead of &&?
  • Marc B
    Marc B over 8 years
    @Jessica: no. then ANY image type would pass. it's a != comparison.
  • Tilak Madichetti
    Tilak Madichetti about 7 years
    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. - Docs
  • Derek Brown
    Derek Brown over 6 years
    Your post was flagged as low quality because it was all code. Try explaining what you did.
  • cottton
    cottton about 6 years
    "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." See php.net/manual/en/function.getimagesize.php
  • schlimmchen
    schlimmchen over 4 years
    The manual says that the file stuffed into getimagesize must be a valid image. To check for the content type of a file, use mime_content_type instead, see php.net/manual/en/function.mime-content-type.php
  • SteppingHat
    SteppingHat about 4 years
    This is BAD and opens up your site to potential remote code execution. Anyone can put exactuable code inside the image header (where the metadata is stored and text is considered valid) and getimagesize will still think it is an image, thus accepting the file and potentially allowing PHP code to be executed server side. Use mime_content_type instead.