views:

66

answers:

3

This is what I want an user to be able:

  • Upload ANY file to the server (attachment) to the uploads folder
  • Be Able to download it afterwards

So I have created this dir with the following .htaccess

Allow from all
DirectoryIndex .x
php_flag engine off
Options -Indexes
Options -ExecCGI
AddType text/plain .html .htm .shtml .php .php3 .php5 .phtml .phtm .pl .py .cgi
ForceType applicaton/octet-stream

My question is, is this secure?

+3  A: 

I would like to say: no

It should be more secure if you deny access from all and manage the download via a script that deliveres the files. Furthermore you should rename the files, so that there e.g. nobody places his own htaccess or whatever. The original filenames you can store in a DB.

Why: You will never know what happens in the future, some files can later get executable, somewhere else you place an insecure script that allows users to include those uploaded files, and so on.

Dr.Molle
So, I rename the file to MD5('test') for example, and deliver the download with a script, place the uploads outsite WWW and .htaccess them "Deny from all"?
Kevin
Yes, this would be much more secure. Additional you should ensure that none of your own scripts on the server will ever be able to include one of these files.(this cant be done via .htaccess, you have to setup open_basedir to a directory-path that is not containing the upload-folder ) . If you place the directory outside DOCUMENT_ROOT you dont need .htaccess, the directory anyway cant be accessed via HTTP
Dr.Molle
A: 

I agree that it would be much better to download them via special script. But if it's not possible, do two things:

  1. If you wish users to be able to download files, you can add attachment HTTP response header Header set Content-disposition "attachment" which will force browser to download file instead of rendering it. Still, you have to make sure files won't be accessible through other potential vulnerabilities like File Inclusion.
  2. Forbid execution for upload directory with chmod -R a-x
p0deje
+2  A: 

I also agree with Dr.Molle that you should rename the files and send them dynamically.

But instead of sending them via a script, which will take up much more memory than necessary, I highly recommend using mod_xsendfile for Apache.

With mod_xsendfile, instead of outputting the file through PHP, you can simply send the XSendFile headers:

<?php
    header('Content-Disposition: attachment;filename=originalname.txt');
    header('X-Sendfile: /path/to/file.txt');
?>

This way, you can keep all the files OUTSIDE the web directory root and therefore completely inaccessible to the outside world. You won't have to worry about .htaccess at all.

If your host allows you to install new Apache modules, you'll need apxs installed (it probably will be). If it's not installed, you'll need to rebuild Apache with apxs enabled. In my experience, if you can manage it, it's worth it. XSendFile saves SO much trouble.

willell