0

I have been researching this topic for the last couple weeks now and it's really beginning to bug me that I can't find a definitive answer for it.

I have a website where users are able to upload their own profile picture. I want to ensure the only files that are allowed to be uploaded are JPEGs, GIFs and PNGs

Obviously using the mime type sent by the browser to validate is a big no no as it can easily be spoofed so that rules that out, and it goes without saying never to validate on the file extension.

Next there is the new(ish) finfo functions PHP provides. I have been using this for the time being as it seemed to be the best available method but reading the comments at http://www.php.net/manual/en/ref.fileinfo.php it seems that can be tricked too. Also I'm not sure if just checking if the returned MIME type is image/jpeg, image/gif, or image/png is too restrictive?

Then there is the getimagesize() function which I read returns false for anything not an image which seems perfect, but if that is the case why are there so many accepted answers on here saying use finfo?

Lastly there is the system() or exec() call, which seems a bit dangerous allowing the user to specify part of a system call!

So my question is, what method should I use? I want to make my script as secure as possible but also open enough so regular users don't get punished in their valid images being rejected by the script

Andy
  • 4,901
  • 5
  • 35
  • 57

2 Answers2

0

this is just my 2 cents, but maybe it can help. I would at least use these 3 steps below:

  1. Check the files with getimagesize() and MIME type to begin with.
  2. When moving the files/resizing etc, save the file without and extension (images will still render without extensions.
  3. use some htaccess in the uploads directory like:

    AddHandler cgi-script .php .php3 .php4 .php5 .phtml .pl .py .jsp .asp .shtml .sh .cgi .html .htm .js AddType text/html *.htm *.html AddType application/x-httpd-php-source *.php

I would love to know more about this as well!

MrE
  • 1,124
  • 3
  • 14
  • 28
0

Using image library to open it and then resave will ensure the result to be an image. If you don't want that, use the best available option (like finfo) and just be sure to save the file in a way that it will never be executed by the server. Forbidding extensions like php and saving the file with an arbitrary name should do the job, but it depends on server configuration!

Hugo Mota
  • 11,200
  • 9
  • 42
  • 60
  • When you say save the file in a way it will never be executed, do you mean through the permissions of the file/directory? – Andy Sep 26 '12 at 08:09
  • @Andy No. Servers that handle php are normally configured to execute files with `.php` extensions (maybe `.PHP` too). So you have to be careful. If you use user-specified names for the files they could trick the server too. They could even traverse through the file system and save the file wherever they want (with names containing `../`). Thats why i recommended arbitrary names. – Hugo Mota Sep 26 '12 at 15:54