Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Secure User Image Upload Capabilities in PHP

I'm implementing a user-based image uploading tool for my website. The system should allow any users to upload JPEG and PNG files only. I'm, of course, worried about security and so I'm wondering how the many smarter people than myself feel about the following checks for allowing uploads:

1) First white list the allowable file extensions in PHP to allow only PNG, png, jpg, JPG and JPEG. Retrieve the user's file's extension via a function such as:

return end(explode(".", $filename));

This should help disallow the user from uploading something malicious like .png.php. If this passes, move to step 2.

2) Run the php function getimageize() on the TMP file. Via something like:

getimagesize($_FILES['userfile']['tmp_name']);

If this does not return false, proceed.

3) Ensure a .htaccess file is placed within the uploads directory so that any files within this directory cannot parse PHP files:

php_admin_value engine Off

4) Rename the user's file to something pre-determined. I.E.

$filename = 'some_pre_determined_unique_value' . $the_file_extension;

This will also help prevent SQL injection as the filename will be the only user-determined variable in any queries used.

If I perform the above, how vulnerable for attack am I still? Before accepting a file I should hopefully have 1) only allowed jpgs and pngs, 2) Verified that PHP says it's a valid image, 3) disabled the directory the images are in from executing .php files and 4) renamed the users file to something unique.

Thanks,

like image 939
flight643 Avatar asked Sep 04 '10 21:09

flight643


People also ask

How can upload image more than 2mb in PHP?

To increaes file upload size in PHP, you need to modify the upload_max_filesize and post_max_size variable's in your php. ini file. In addition, you can also set the maximum number of files allowed to be uploaded simultaneously, in a single request, using the max_file_uploads . Note that from PHP 5.3.


2 Answers

Concerning No. 2, I read on php.net (documentation of the function getimagesize() ):

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.

like image 57
Hanspeter Siegfried Avatar answered Oct 15 '22 18:10

Hanspeter Siegfried


Regarding file names, random names are definitely a good idea and take away a lot of headaches.

If you want to make totally sure the content is clean, consider using GD or ImageMagick to copy the incoming image 1:1 into a new, empty one.

That will slightly diminish image quality because content gets compressed twice, but it will remove any EXIF information present in the original image. Users are often not even aware how much info gets put into the Metadata section of JPG files! Camera info, position, times, software used... It's good policy for sites that host images to remove that info for the user.

Also, copying the image will probably get rid of most exploits that use faulty image data to cause overflows in the viewer software, and inject malicious code. Such manipulated images will probably simply turn out unreadable for GD.

like image 41
Pekka Avatar answered Oct 15 '22 18:10

Pekka