simple solution for restricting access to (some) uploads/downloads

Initial Situation

For a site I’m setting up I was looking into the whole field of securing uploads/downloads and restricting access to them based on user roles/capabilities. Of course I have read some of the previous questions related to the (general) topic on here, for reference reasons the most important/interesting ones I found:

  • How to Protect Uploads, if User is not Logged In?
  • How to restrict access to uploaded files?
  • Restricting access to files within a specific folder
  • How to make media upload private?
  • Merging PHP download script into `functions.php`

Supplementary notes

Generally it is not a bad idea to additionally improve security of your wordpress installation – for example protecting your wp-config.php – there are a lot of things you can and should do. There is a ton of information out there how to do it. I’m in the context of this question mostly concernd about my uploads/downloads.

WordPress uploads aren’t secured, everybody can browse the uploads folder, unless you prevent it with a .htaccess:

Options All -Indexes

The .htaccess file has to be placed inside the uploads folder. But that isn’t really securing them, it just makes it harder to find the files. Additionally you can prevent hotlinking, esentially restricting access based on referrer – although that is little bit differnt case i thought i mention it, I’m not further elaborating, you can find plenty of information about that.

Of course has the possibility to make posts private or create a custom post type with suitable template files to make that post type private, but thats not securing your files. Same can be said for wrapping the files in conditionals like is_user_logged_in() or is_admin().

On a sidenote there are plenty of plugins out there which are promising to make your files secure and protected, but many of them are just pretending to do so, some of the reasons are above. I’m just poiting that out because I’m pretty sure that it is not known by everyboby – so, be aware of that.

Objective

My intention was to be able to restrict access to (some) uploads and respectively downloads. And to make sure that nobody unwanted could have access to them, not by chance or if that someone knew the filename, the files should be really private and secure. After all only certain people should have access without exceptions.

Additionally i had no need to privatize the whole site, indeed that would be counterproductive – it is used for public presentation purposes. Further more i wanted the solution to be easily usable, for the simple reason that some of the people working with it are not exactly computer experts, as it is often the case.

Question

Hence the question, is there an (relatively) simple way to restrict access to (some) uploads and the respective downloads? And like I carried out, that means a way to really protect and secure them?

1

I’m hereby answering my own question, because i found a solution, but I’m really interested in your opinions towards it. Or maybe you have a much better solution, if so, I really would like to here about it.

Research result

My research results were:
1. get the files outside of the document root, www folder;
2. disallow any direct access to the folder containing the files;
3. let a script handle the requests to the files;
The sources for those points are – at least mostly – included in my question.

Solution

  1. I installed the plugin »wp-downloadmanager«
    • a folder called files will be created inside wp-content in the process;
  2. I added a .htaccess file to the new files folder:
    • content of the .htaccess:
      Options All -Indexes
      Order Deny,Allow
      Deny from all
  3. I changed one important option of the plugin:
    • the option I mean is download method;
    • I changed it to output file;
  4. I added some files over the plugin interface:
    • there is a option called allowed to download;
    • which allows to restrict access based on user role/capability;
  5. I did some testing:
    • no direct access to the files – not over the addressbar or wget;
    • public downloads can be reached via their permalinks – I choose »nice permalinks: yes« and »download url: file id« on the options panel – addressbar/wget is working too;
    • protected, restricted downloads are only accessible if logged in as user with the correct role/capabilities;

Concluding thoughts

I’m thinking the solution pretty much follows the research results. Apart from placing the files outside. But restricting access to/protecting the directory and let a script handle file requests is fullfilled. The restriction of access is handled by the .htaccess and the script in this case is the plugin wp-downloadmanger.

Supplementary notes

  • it is absolutely necessary to change the download method to output file
  • and of course it is a must that the .htaccess file is in place

  • to check on the fact that the plugin takes over the role of the script take a look at wp-downloadmanger.php – about lines 207 to 227 (version 1.6.1); this is meant as complementary point to the linked information

Leave a Comment