I wrote a web site for a small company several years ago, while I was studying. I have come to the realization that my security skills were not as good as they should have been, and recently the site was hacked and malicious php-code was uploaded using a form which was meant for image uploads.
I have since moved on to the .NET world and whilst I know how to secure file uploads in .NET I really have no idea how to do it using PHP. I am sorry that I can not provide any source code, and I am therefore not expecting anyone to post any direct fixes for my code.
What I hope is that someone can show me a good approach to server-side analysis to ensure that the uploaded $FILES array content is in fact an image or an audio-file, or at the very least that it is not a php-file.
Glad you asked. This is a tricky subject, and few application developers are aware of the security risks.
I'll give you a summary of the approaches you should take, and some reading to learn more. Make sure you read the additional reading, because my summary is incomplete.
Summary:
Host the user-uploaded content on a separate domain. This is the most important and reliable defense you can take.
Check the MIME type of the uploaded file, when it is uploaded, to make sure it is on a whitelist of safe MIME types. Generate a new random filename to save it under. In the case of some file types, such as images, Consider re-coding it (e.g., transform to PNG, or use ImageMagick to convert it from its filetype to the same filetype), as this may defeat some attacks.
When the file is downloaded/retrieved, make sure to set the Content-Type:
header explicitly to the safe MIME type. Also set a X-Content-Type-Options: nosniff
header. If you don't intend for the file to be viewed in the browser, send a Content-Disposition: attachment
header, too, to make the browser treat it as a file download.
Scan file uploads for viruses or malware.
Reading:
What steps should be taken to validate user uploaded images within an application?
MIME sniffing protection
Is it safe to store and replay user-provided mime types?
Is it safe to serve any user uploaded file under only white-listed MIME content types?