I've got a site that accepts user-uploaded files (images, pdfs, word docs, etc.) then allows other users to download them.
I realize this presents a security risk, since malicious users could upload scripts etc. that masquerade as useful files.
My question is this-- is it enough to check the mi开发者_运维问答me type of the file being uploaded using PHP (mime_content_type or finfo) and set the file to read only (non-executable), or must I also store the uploaded files in a directory that is outside the web root? I would think this would eliminate most of the risk from the uploaded file, but I'm not sure. Performing a virus scan on uploaded files is not possible in this situation.
Thanks for input.
A common practice is to upload files outside the document root, and typically using randomized filenames which are then mapped to the correct item/object/post in the database. If additional permissions are needed to access the files, make sure you check them before allowing downloads, and of course you'll have only authenticated users uploading.
Fileinfo finfo_
is useful for validating most mimetypes, at least to verify that something called ".txt" is actually a text file and not a binary blob, or that a ".jpg" really appears to be a jpeg based on its first few or last few bytes. It may require some extra work sorting out MS Office mimetypes, as if I recall correctly, they all come out as application-msword. But you can then use the file extension to figure out what it is really supposed to be (xls, ppt, doc, etc).
A PHP script then supplies the downloaded file, rather than the web server directly serving it. For that reason, you should store the mime type along with it, so that you can serve the appropriate headers.
header("Content-type: application-whatever");
header("Content-length: size-of-the-file-in-bytes");
I can recommend you use every tool at your disposal to test for the file type. But know that there are other ways a hacker can implant a dangerous file.
Your best bet is to have the files be uploaded to a different server. One that can only host files.
I would check the mime type of the file but I wouldn't rely on this. Even if the file is a full blown .gif
and contains a comment in its id3 tag which is a php, it can be executed with a local file include. A safer approach would be store files in the database using a long blob
datatype. However this kind of overhead is crap.
The best solution from the perspective of security, scalability and perforce would be to use a no-sql database like CouchDB.
A few things to keep in mind, don't trust $_FILES[]
. $_FILES['type']
could be anything the attacker wants so there is no point in checking it from a security perspective. And $_FILES['name']
could have nasty input like ../../../
. Its best to rename files to the primary key and then store information about that file in a relational database (like mysql).
精彩评论