I have created a new content type with an Image field, and I've set it to save in private directory. In my configuration > File System, I have specified /sites/default/files/private as my private directory. File is saving to private directory as well. But when I open that private Image having url structure like /system/files/ in another browser. It shows up, It should not have shown in other browser. How can I make it private?

3 Answers 3


Drupal should have created an .htaccess file in that directory with Deny from All per the File documentation. Check to see if this is the case. This post may also be helpful: Noob question about private files and Content Access.


The best way to make sure it is private, is to locate the private directory outside of the web root.

The path /sites/default/files/private looks like its relative to the web root. In file system terms it may be something like:


(what is before "sites" depends on your Apace configuration, so this is just an example.)

To make it private, place it in a directory close to your file system root (above the web root).

For example:


If for some reason you will have it below the web root, you need to use Apache directives to protect access to this directory (the file system permissions are not enough, because they only determine whether the web server user shall have access - the file system has no idea about whether the user trying to access the file through the web server user is a logged in Drupal user or just anonymous, and the web server user will be happy to serve it to the anonymous user unless told otherwise).

In other words, you need to have an .htaccess file in the private directory to instruct Apache to protect it. Drupal usually adds this file for you when you set up the private directory, so you should first check whether an .htaccess exists in the private directory, and whether it has the right content.

Its content should be as follows:

Deny from all

# Turn off all options we don't need.
Options None
Options +FollowSymLinks

# Set the catch-all handler to prevent scripts from being executed.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
  # Override the handler again if we're run later in the evaluation list.
  SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003

# If we know how to do it safely, disable the PHP engine entirely.
<IfModule mod_php5.c>
  php_flag engine off

If it exists, and has the right content, but does not work, then your Apace configuration is wrong. Make sure t Apache's AllowOverride are enabled for your Drupal site.


When using Private file mode, I usually enforce access control on those files with


Control access to private file downloads and specify HTTP headers.

This hook allows modules enforce permissions on file downloads when the private file download method is selected. Modules can also provide headers to specify information like the file's name or MIME type.

For example:

 * Implements hook_file_download
function MODULE_file_download($uri) {

  // You can define your own permission with hook_permission
  if (!user_access('access content')) {
    // Access to the file is denied.
    return -1;


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.