See the official online handbook for more information about securing private files. The information about private files starts at the "Managing file locations and access" header.

In order to make a private download truly private, you need to move the files directory (usually under sites/default/files) into a new place outside the Drupal installation. It should be in a place the user can't access via browser.

This tutorial is written based on my Dreamhost shared account. It is assumed you have shell (SSH) access to your host.

Here are the the steps:

  1. Install Drupal.
  2. Connect to your host via shell.
    ssh USER@example.com
  3. Create the new file directory.
    mkdir MY_FILES
  4. Set it's permissions to 700 (only owner can read, write and execute).
    chmod -R 700 MY_FILES
  5. Set you domain permissions to 505 for increased security (owner and public can read and execute).
    chmod -R 505 example.com
  6. Let's get the path to your new file directory.
    pwd MY_FILES
  7. Copy the response (should be /home/XXX).
  8. It's time to tell Drupal where the new file system is. In admin/settings/file-system change the file path to what you copied before and the new file directory (e.g. /home/XXX/MY_FILES).
  9. Do the same for the temp directory (e.g. /home/XXX/MY_FILES/tmp)
  10. Optional: If you already have files uploaded you can change their location with the following SQL, although you should be very careful with such changes.
    UPDATE files SET filepath=REPLACE(filepath, 'sites/default/files', '/home/XXX/MY_FILES')

Comments

chipw’s picture

I am using ubuntu, have everything newly setup and created the new files directory for private downloads. I did chmod -R 700 on the directory and went back to the config page but it says the directory is not readable, which is true. I tried 755 as well, but ended up using 777 to get the Site Configuration page to be happy with it.

allwires’s picture

I also had the same problem. I am using the host small orange and setting the permissions to 700 did not work. I had to set it to 777 like chipw had to do.

mErilainen’s picture

Why does the root have to be outside Drupal installation? It makes it more difficult to set up in some servers, where I don't have enough permissions.

Currently I have it under sites/subsite.com/files and Drupal denies access to a file if I'm not logged in. So what downsides are there having it in this path?

ghosty’s picture

If I know the direct url to your file, then I can download it without even being a user. For instance, if you have a file at sites/subsite.com/files/mypicture.jpg, then I just need to go to http://www.mysite.com/sites/subsite.com/files/mypicture.jpg. By putting the directory outside the web root, you make it non-accessible to url direct path downloads.

slauriault’s picture

Hi,
Running Drupal out of xp. Gives me the following message whenever I set download method to private and designate a path outside htdocs directory. My settings work actually, but still gives this error message in status report.

marcoka’s picture

with 777 drupal displays an error, yes. so step 4 should be corrected.
another info. if you use filefiled/imagefield a user that has access to the node/view the imagefield, can access and download your ORIGINAL file! Remember that.

Martin.Schwenke’s picture

Depending on what modules you're using you might need to clear the cache after switching to private uploads. Doing a Google search for "drupal clear cache" should show how this is done. Note that if you're using CCK modules for attachments, such as FileField and ImageField, then you'll need to clear the cache_content table too or links to some images/attachments will be stale and frustration will probably follow... ;-)

asb’s picture

Strange... when using the private download method, the theme's logo get's stored in /tmp (and is not being rendered). Very strange... :-(

gjmokcb’s picture

After following all steps above, and when not logged in, I can still access an image file by going to http://mydomain.com/system/files/filename.jpg.

I'm set for private download, the folder is outside my web directory, folder perms are set to 0700, images are being stored in the designated folder, but I can access it with my browser. What's up?

gjmokcb’s picture

Interesting. I added a line to my .htaccess file in the folder where the restricted file folder resides, but no change. (That should have been unnecessary in a private download context.) Then I changed my filefield settings, checking "cleanup using Pathauto" for both the filefield and filepath. (That shouldn't have made a difference.) Now I can't access the files from outside Drupal. All is working correctly. Drupal never ceases to amaze.

subu.purohit’s picture

When I set file system path to /var/www/MY_FILES then my new downloading path is :
http://mydomain.com//var/www/MY_FILES/filename.jpg which redirects me to page not found and file is uploaded in /var/www/MY_FILES . I followed the steps above and don't know what I am missing . :(