Hey guys, I have searched around a bit, and have not really found a professional type response to how to have secure fileupload capability so I wanted to get the opinion of some of the experts on this site. I am currently allowing upload of mp3s and images, and while I am pretty confident in preventing xss and injection attacks on my site, I am not really familiar with fileupload security. I basically just use php fileinfo and check an array of accepted filetypes against the filetype. For images, there is the getimagesize function and some additional checks. As far as storing them, I just have a folder within my directory, because I want the users to be able to use the files. If anyone could give me some tips I would really appreciate it.
No, because this could easily be spoofed. There's an article that describes how a server could be attacked by uploading a 1x1 "jpg file" and how to prevent it. Good read.
The first thing to do would be to disable execution of any server side code (e.g. PHP) in that directory via server configuration. Setting up a whitelist for MIME types (or file extensions, since your server uses those to figure out the mime type in the first place) and only allowing media files (not HTML or anything) will protect you from XSS injections. Those combined with a file type check should be quite sufficient - the only thing I can think of that might get through those are things that exploit image/audio decoders, and for spotting those you'd need something close to a virus scanner.
I usually invoke ClamAV when accepting files that can be shared. With PHP, this is rather easily accomplished with php-clamav.
One of the last things you want to do is spread malware around the globe :)
I mentioned this only because the other answers had not, in no way did I intend this to be a complete solution.
"malicious" files are not the only way to hurt your server (and if your site is down, it hurts your users).
For example, a possibility to hurt a server would be to upload a lot of very small files :
- it would not use all the space on the disk,
- but could use all available inodes...
...And when there is no free inode left, it's not possible to create any file anymore ; which, obviously, is bad.
After that, there is also the problems like :
- copyright
- content that is not OK to you or your users (nudity ? )
For that, there's not much you an do with technical solutions -- but an "alert the moderator" feature is oftne helpful ;-)
To start with the "file-type" ($_FILES['userfile']['type']) is completely meaningless. This is a variable in the HTTP post request that can be ANY VALUE the attacker wants. Remove this check ASAP.
getimagesize() Is an excellent way to verify that an image is real. Sounds files can be a bit more tricky, you could call file /tmp/temp_uploaded_file
on the commandline.
By far the most important part of an uploaded file is the file's extension. If the file is a .php, then you just got hacked. It gets worse, Apache can be configured to ignore the first file extension if it doesn't recognize it, and then use the next extension, so this file would be executed a normal .php file: backdoor.php.junk
. By default this should be disabled, but it was enabled by default a few years ago.
You MUST MUST MUST use a file extension White List. So you want to force using files like: jpg,jpeg,gif,png,mp3
and reject it otherwise.