Verifying an uploaded image is really an image

Years ago I ran a BBS (Bulletin Board Service) that when a user uploaded any file to the board it would scan the file’s integrity. Well, I’m just trying to do that now, but only with image files. Right now I have it where a person can upload an image to my server, but I’m pretty sure it has security vulnerabilities. A temporary fix that I’m going to employ is where only the sysop (system administrator) will be able to upload a image, but in the distant future I want allow verified users to be able to upload images.

Here is my image upload class:

[php]<?php

class ProcessImage {

/* Image Section */
public $image;
protected $errMsg;
protected static $allowedExts = array("jpg", "jpeg", "gif", "png");
protected static $allowedTypes = array("image/gif", "image/jpeg", "image/png", "image/pjpeg");
protected $imageName;  // Image Name;
protected $imageType;  // Image Type;
protected $dirName;    // Image Directory;
protected $imageExt;   // Image Extension	
protected $imageError = NULL; // Image Error;
protected $imageSize;  // Image Size;
protected $imageTemp;  // Image Temp;
protected $subDirectory;
protected $uniqueName;
protected $uniqueNamePart;
protected $uniqueNumberPart;

// Create constructor to process image:
public function __construct(array $file=NULL, $fileNumber=NULL) {
    $this->image = $this->processImage($file, $fileNumber);
}


// Process the image and move the file to the upload directory:
protected function processImage(array $imgFile=NUll, $name=NULL) {
    $db = Database::getInstance();
    $pdo = $db->getConnection();

    $query = "SELECT * FROM pictures";
    $result = $pdo->query($query)->fetchAll();

    $fileNumber = count($result) + 1;
    if ($fileNumber < 10) {
      $this->uniqueFileName = $name . '0' . $fileNumber;
    } else {
      $this->uniqueFileName = $name . $fileNumber;
    }

    $this->uniqueFileName . '<br>';

    $this->imageName = $imgFile['name'];
    $this->imageType = $imgFile['type'];
    // Get the image extension:
    $this->dirName = pathinfo($imgFile['name'], PATHINFO_DIRNAME);
    $this->imageExt = pathinfo($imgFile['name'], PATHINFO_EXTENSION);
    $this->imageError = $imgFile['error'];
    $this->imageSize = $imgFile['size'];
    $this->imageTemp = $imgFile['tmp_name'];

    if ($this->imageSize > 800000) {
        return $this->imageError = "Image is greater than 800K";
    }

    if (!in_array($this->imageExt, self::$allowedExts)) {
        return $this->imageError = "File isn't an image.";
    }

    if (!in_array($this->imageType, self::$allowedTypes)) {
        return $this->imageError = "Unknown Image Type!";
    }

    /* Unique filename plus path to the image */
    $this->uniqueName = 'lib/images/' . $name . '/img-' . $this->uniqueFileName . $this->dirName . $this->imageExt;
    
    // If no errors move the image to the upload directory:
    if (!$this->imageError) {
        move_uploaded_file($this->imageTemp, $this->uniqueName);
        return $this->uniqueName;
    }
}

}[/php]

Even if someone could direct me to a script that would scan the file integrity that would be very much appreciated. I have personally done an internet search for something like this, but came up empty.

Best Regards,
John

Checking the file type is pointless cause it can be faked. Checking the extension is a “ok” way but not totally secure. The only for sure way to make sure a image file is actually an image is to use the getimagesize() on it and see if it returns true or false. If it returns false then you know for sure it’s not an image to begin with.

Thanks, I think getimagesize() will do the trick.

Sponsor our Newsletter | Privacy Policy | Terms of Service