Blog

Storing file uploads above webroot in EE2

2010/11/30

I'm sure many have already read how to run ExpressionEngine with the system directory above webroot, as well as the great article on Securing EE2 on EE Insider by using similar techniques. I was wondering, however, if this was possible with EE's upload directories. Of course, file access from your browser would not be possible without some special coding or creating a symbolic link to your upload directory, but what if you wanted it that way?

Let's say, for example, that a user fills out a form built with Solspace's Freeform module and attaches a file, which in turn gets sent to you by email and is also stored in one of your upload directories. However, you also want that file to stay out of reach from the outside world. An upload folder above webroot in this case would do the trick. Blocking/password protecting the folder below webroot with an .htaccess file, or playing with the folder's permissions could also do, but can be complicated in some cases. Let's go with placing the folder above webroot here.

Given the following EE installation structure, with "uploads" being the directory in which files are uploaded:

/public_html
     /images
     index.php
     /system
     /expressionengine
     /uploads

First move your "uploads" folder above root:

/public_html
     /images
     index.php
     /system
     /expressionengine
/uploads

Then, in EE's control panel under Admin => Content Administration => File Upload Preferences, create a new upload directory and write the full path to your uploads folder:

Server path to Upload Directory: /path/to/uploads

A relative path can also work. In this case, the "../../" goes to our uploads folder above both our system and public_html directories.

Server path to Upload Directory: /../../uploads

Unless you have a symlink or other fancy way to access files above webroot, you can write a non-working URL in the "URL for Upload Directory" field: this will keep your files inaccessible from the outside world.

Save these settings and that's it! Set up a freeform form with an upload field, and set the file_upload="" parameter to the name of your Upload destination, as well as the notify="", send_attachment="" and template="" parameters:

{exp:freeform:form file_upload="Upload directory" notify="me@mydomain.com" send_attachment="yes" template="my_email_template"}

	// Your form with a file upload field

{/exp:freeform:form}

If someone completes your form and attaches a file, the file will be sent to you by email and be stored in your uploads folder. You could set the form not to send the file, and the file would only be stored in your uploads folder.

Another way to use your uploads folder above webroot is through EE2's file manager. Uploading files this way also stores them in your uploads directory. Again, depending how you set up the URL for the upload directory, you may not be able to access the file from your browser, even from the Control Panel. FTP, SFTP, etc would give you access to the file, of course.

I'm sure there may be other ways to deal with "secret files", as is often the case with doing anything in ExpressionEngine, given it's flexibility. I'm also sure there are also ways of working on top of what is presented here to make things even more interesting. I agree this isn't a perfect solution for all situations, but I hope this tip might come in handy for some special cases dealing with uploaded files.


Comments

Comments

Aaron Waldon said on 2010/12/15:

Storing files above web root can be extremely useful. We setup our EE image manipulation plugin, CE Image, to be able to work with source images stored above web root. That way, the full size source images that need to be protected, like for photography sites, can remain out of reach for web users, but they can still be used to create thumbnails or watermarked versions of the photos that are web accessible.

Great writeup on a very useful subject!

Nicolas Bottari (Admin) said on 2010/12/22:

Thank you for your comment. I didn’t think of that use! That’s a great idea.
Does you addon allow for specifying absolute paths as a parameter?

Aaron Waldon said on 2010/12/22:

Thanks Nicolas. Yes, I have gone to great lengths to try and make the source as flexible as possible. You can pass in the full server path, relative path to web root, absolute path to web root, a URL, or even an external URL. The documentation for the plugin can be found here: http://www.causingeffect.com/software/ee/ce_img