I'm currently very confused by how private files work:

  • I have a content type that has an image field and a file field. Both are set up to use private file access for their contents.
  • Node access on the content type is working correctly.
  • A user who does not have access to the node cannot get to the contents of the file field -- they get an access_denied page when they try to load the URL of the file.
  • However, they DO have access to the image file, via the image's url (/system/files/...): hitting the image URL in a browser brings it right up.

Are there any insights out there about why the image file is leaking through, and what I can do to stop it? I've explored hook_file_download and hook_file_download_access, and have been putting watchdog statements throughout the image and files modules trying to track this down, but to no avail. Thanks!

1 Answer 1


There are three implementations of hook_file_download(), in Drupal:

The first two implementations always check the user has access to the entity to which the file is associated; the third one doesn't check that, but it only checks the directory containing the file is the one used for the user profile's pictures.

function user_file_download($uri) {
  if (strpos(file_uri_target($uri), variable_get('user_picture_path', 'pictures') . '/picture-') === 0) {
    $info = image_get_info($uri);
    return array('Content-Type' => $info['mime_type']);

If there isn't any other module implementing hook_file_download(), I would expect the users to be able to access the files through http://example.com/system/files when the URI points to the same directory containing the images used for the user accounts.

  • Yeah -- I had run into those functions while trying to figure out what was going on. What I found was that image_file_download was allowing access, down in the "Private file access for the original files" area. Also, btw, the files in question are not being saved in the user_picture_path directory. Anyway, I put together a hook_file_download() handler that, by borrowing some code from image_file_download, checks the assigned node and does the right thing re access. I'm still not sure why it's not just happening has part of the basic system; maybe I'm messing something up elsewhere. Thx!
    – Jim Miller
    Commented Dec 10, 2012 at 17:25

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.