explicit permission by roles for private files

drpratten - January 3, 2007 - 10:59
Project:Drupal
Version:5.x-dev
Component:system.module
Category:feature request
Priority:normal
Assigned:Unassigned
Status:won't fix
Description

The private file system has no mechanism for restricting access by roles.

I propose the following small patch to system.module

/**
* Implementation of hook_perm().
*/
function system_perm() {
  return array('administer site configuration', 'access administration pages', 'select different theme','able to download private files');
}

/**
* Implementation of hook_file_download().
*
* Ensure that only authenticated users can access file downloads.
*/
function system_file_download($file) {
  if (!user_access('able to download private files')) {
    return array(-1);
  }
}

#1

RobRoy - January 3, 2007 - 21:06
Status:active» won't fix

Permissions should have nothing to do with private files. You can only have public OR private files, so we permit access to just files. Also, things like this can be achieved with contrib modules.

#2

drpratten - January 5, 2007 - 20:49

Thanks for your feedback. I would like to ask Drupal Core Team to reconsider my request.

Permissions has much to do with private files.

The current situation is that:

  • through admin/settings/file-system the admin may 1) set the "files" folder to be not accessible over the web and 2) force all downloads to go through system/files which is served by system.module's file_download() . The combination of these gives the possibility of controlling access to downloads by role.

    This feature is presented to admin as a site-wide feature - however there is no site-wide mechanism for enforcing permission by roles. This leads to duplication of authorisation code.

  • upload.module enforces "view uploaded files" permission by role for files that it knows about
  • imce.module completely breaks this mechanism by granting access to uploaded files without checking permissions

Now - you could say that imce.module has a bug in it. It "should" check permissions. But if the meaning of "private" is determined on a contrib module by contrib module basis - there will be a profusion of permissions which may contradict each other.
My conclusion is that the access permissions for a site-wide a private filesystem should not have been left up to imce.module in the first place.

System.module serves up the private files. It provides the a simple place to enforce access control by role for private files.

It may be a good idea as part of this change to remove "view uploaded files" permission from upload.module since there should be a single point of control.

This proposed change would mean that imce module does not need to fix this bug: http://drupal.org/node/107068

#3

lordzik - August 18, 2008 - 08:25

I've been fighting with files permission and IMCE for few days and i've finally found this solution. I've applied the proposed patch and ALMOST all my problems with file permissions are gone. I think this should be applied to the core Drupal ASAP. I (and i suppose many more people) use IMCE for file management (sorry guys, but i have to say it: Drupal's native filemanagement is a crap. I don't know how people can live with no possibility to add a link to a file inline in page's body and a series of links to files at the bottom of the page...) and without this patch anyone can download 'private' files if he knows a link to it (i restrict access to a page with nodeaccess module - somethink like that should be directly implemented in Drupal too!).
Moreover - i think that you should think about adding a 'categories' for files. Imagine that you have few roles and you want to add a file that only one of the roles should able to download and the second file for another role. And the third file you want to be available for everyone (anonymous user).

Regards.

#4

-Anti- - August 20, 2008 - 21:15

> and without this patch anyone can download 'private' files if he knows a link to it

By 'anyone', you mean anyone who is *logged in*?

Just to clarify, what the original poster is complaining about is that anyone who is logged in can view a file in the private folder (if they know the url) even if they don't have permission to view the node it is in, *except* if the file is uploaded by the core upload feature, in which case it is protected by the node viewing permission.

This is still an issue with D6.


If you meant anyone on the internet can download private files by direct linking,
then you haven't properly set the file system to 'private' then. An explanation follows:

If drupal is in root, the 'file system path:' field should be ../private
If drupal is in a subdomain or folder, the 'file system path:' field should be ../../private

This creates a folder above your public_html directory (sometimes called httpdocs).
No-one can link to that file direct from the internet.
But drupal *can* by using a relative link, and to make things easier it uses the alias /system/files/

If you use the upload module, files will end up in /home/accountuser/private on your server.
Within drupal the link to that file is: /system/files/image.jpg
The absolute link is http://domain.net/system/files/image.jpg

And here's the thing - if you are logged out of drupal, putting that absolute link into your browser bar
will bring up an access denied page. You can only get to the image by being logged into drupal.

IMCE knows all this.
If you state in the IMCE profile settings for a user to have the path: /images/%UID
then the path to an image in that directory on the server will be:
/home/accountuser/private/images/%UID/image.jpg
When users 35 inserts an image using IMCE, the html in the text area will read:
img src="/system/files/images/35/image.jpg"

#5

me@andy-j-thorn... - August 21, 2008 - 04:13

Hey Anti,

Are you sure that is how it works? Is it possible it got broken in a recent 5.x version of Drupal?

I have got 'private files' set in Filesystem. The directory it refers to above/outside of my public_html. The directory has permission 7,0,0. There is a .htaccess which has 'Deny from all' (perhaps not necessary but I am trying anything at this stage). In Access Control I have no check marks against anonymous users (e.g. Access Content is NOT set). I am also using IMCE. I log in, create a page with an image file on it (the file does indeed get created in my private file area). I log out of my drupal and can still access the image directly, as I am sure you will be able to too.

http://www.andy-j-thornton.com/hdro/system/files/u1/ANDRES_248.jpg

I am using Drupal 5.9. I am reasonably confident I have got everything setup right.

#6

-Anti- - August 21, 2008 - 15:27

The url you give is: andy-j-thornton.com/hdro/system/files/u1/ANDRES_248.jpg

But it should be: andy-j-thornton.com/system/files/u1/ANDRES_248.jpg

> The directory it refers to above/outside of my public_html

Well, the url says that you're file is residing somewhere below: home/public_html/hdro/

I assume you've installed drupal into home/public_html/hdro
In your file system page, you should have ../../private set as your directory.

The first ../ takes you to /public_html, the second ../ takes you to /home
So your file system root becomes: /home/private/.
Both IMCE and the core upload will change the root they use auotmatically.
In IMCE you'll see ../../private at the top of the directory pane.

Put your jpg file in there and you'll see that you can't directly link to it. ie. you can't put:
andy-j-thornton.com/../private/u1/ANDRES_248.jpg into your browser.

But drupal (and imce) *can* link to it internally using a relative link.
However, instead of using ../ drupal obscures it with the string: /system/files/
So after inserting the image with IMCE, the url in the textarea will be:
img src="/system/files/u1/ANDRES_248.jpg"

By the way, you might not realise this, but if you use the private file system, it means
anonymous users cannot see any uploaded images in your nodes, even if you set
the nodes to be viewable by 'anon'.

You can of course setup a basic static site with graphics and downloads for anonymous
users, ftp-ing your images & files to directories in the hdro/sites/default/files folder. But
anything uploaded though the core file upload or IMCE will not be available to anyone
who is not logged in.

If you need a bit of extra flexability, check out the private upload module. Using this, IMCE
will not upload privately, but the core upload will let you choose public or private.

#7

me@andy-j-thorn... - August 23, 2008 - 04:24

Hi,

Thanks for the involved reply. However, you were wrong in assuming I was confused about my path. My drupal IS installed in andy-j-thornton.com/hdro and my private direction IS in ../../. it is a subdirectory 'level' with public_html. it is definitely, definitely, definitely outside of my public_html directory (and files are really being written there - i checked).

p.s. my private directory is actually set in file system path as "../../hdro_private_files" .... the URL http://andy-j-thornton.com/../hdro_private_files/u1/ANDRES_248.jpg does not let me access, but surely http://andy-j-thornton.com/hdro/system/files/u1/ANDRES_248.jpg should NOT work either.

#8

MiMe - August 27, 2008 - 18:45

I guess that the permission to a directory per role basis is only for using the IMCE editor. When a Guest is viewing files no directory permission is checked and the Guest can view the "private" (off site) files.

The URL path to my private files are http://DOMAIN_NAME/system/files/FOLDER_NAME/IMAGE_NAME

The Guest role do not have any permissions (through IMCE) to the private folders.

#9

-Anti- - August 27, 2008 - 19:42

> However, you were wrong in assuming I was confused about my path

OK, then it can be only two things:

1) As you suggested it is broken on the D5 version you're using (it works in D6).
2) Your server is set-up wrongly to allow anon access above root (don't ask me how).

Assuming 1), and assuming that it is the subdirectory which is breaking it, you might
want to try creating 'hdro' as a proper subdomain rather than a subfolder. This means
you could test the private system further, just to see if you can get it to work, by using:
http://hdro.andy-j-thornton.com/system/files/u1/ANDRES_248.jpg
... which is the properly formed url for the private system (ie. no hdro subfolder).

#10

MiMe - October 28, 2008 - 21:10

There is actually a fix for this (to Drupal 6)... though not implemented in IMCE yet...
#266549: directory protection from leeching

#11

robbm - January 30, 2009 - 15:09

I'm really just subscribing to this issue.

It sounds like the proposed patch (and .htaccess tweaks) might solve the file protection issues on a site of mine, so I'm going to give it a try...

 
 

Drupal is a registered trademark of Dries Buytaert.