It's tough to know if this is more related to content_access or drupal core but will try here first.
When using content access to restrict node access, private file attachments are still downloadable. This is due to there being no check in place to see if the current user has access to the node that a file is attached to. As I needed this quickly, I created a light module which does just this. It's not the most elegant as going from FID to NID is not the easiest process.
It would make sense for this to be included with the content_access module.
All that needs to be done is work with the hook_file_download which is called when dealing with private files. Included below is the code I created for handling this. It assumes that a FID is only attached to one node.
/**
* Implmentation of hook_file_download();
*/
function modulename_file_download($uri)
{
//get the current file's fid to work with
$result = db_select('file_managed', 'c')
->fields('c')
->condition('uri', $uri)
->execute()
->fetchAssoc();
//only proceed if the URI produced results
if(count($result))
{
//Get the FID to be used later
$fid = $result['fid'];
//Loop through all possible fields
foreach(field_info_field_by_ids() as $id => $field)
{
//only act on fields of type file
if($field['type'] == 'file')
{
//only act on file fields that are set to private
if($field['settings']['uri_scheme'] == 'private')
{
//column name of the FID in the field's table
$column = $field['field_name'].'_fid';
//main table data
$table_name = 'field_data_'.$field['field_name'];
$results = db_select($table_name, 'c')
->fields('c')
->condition($column, $fid)
->execute()
->fetchAssoc();
//only proceed if a node match was found
if(count($results))
{
//use the entity_id as it's the actual NID
$nid = $results['entity_id'];
$node = node_load($nid);
if(node_access('view', $node))
{
return array(
'Content-Type' => $file->filemime,
'Content-Length' => $file->filesize,
);
}
else
{
return -1;
}
}
}
}
}
}
}
More than willing to answer questions if anything isn't clear or if help is needed implementing this.
Cheers.
Grant
Comment | File | Size | Author |
---|
Comments
Comment #1
Akaoni CreditAttribution: Akaoni commentedThis is more related to drupal core and has been fixed in Drupal 7.1 (and hence Drupal 7.2).
See Access bypass in File module:
http://drupal.org/node/1168756
Comment #2
Akaoni CreditAttribution: Akaoni commentedComment #3
bblancha CreditAttribution: bblancha commentedI submit tht the Drupal core fix solves the problem for registered vs unregistered visitors. It does not however extend the fine node access capability of Content_Access to the file system. So for instance a node available only to a specified group which has file attachments will still allow those file attachements to be accessed by registered users who are not members of the group.
So, I also vote for enhancing content_access to extend the access control to file attachments of the node.
Comment #4
Akaoni CreditAttribution: Akaoni commentedSorry bblancha, didn't see your post as this issue's closed.
Pretty sure Content Access does this already. ??
If not, create a new feature request. ; )
Comment #5
alexkb CreditAttribution: alexkb commentedHope it's ok, but I've tried to re-open the status of this bug, as it's still an issue, and shouldn't really be considered a feature request, as content_access is suppose to restrict access to content as the name suggests.
I've just tested Grant's module in 7.22 with content_access 7.x-1.2-beta1 and it works great. Nice work Grant!
Comment #6
gregglesThanks for your bug report and for helping make this a better module. Could you provide this as a patch?
Comment #7
grantlucas CreditAttribution: grantlucas commentedFrom some tests on the site that was originally seeing this issue, I can no longer access files belonging to nodes which are denied to anonymous users (ie: issue is fixed).
Alexkb, what are the conditions in which you are able to access restricted files? I would like to see if I can reproduce it as well.
Thanks.
Comment #8
jalane81 CreditAttribution: jalane81 commentedI'm having the same problem with my site. I see the code up above and some talk about adding it to the core and it fixes it..
being that I'm a NOOB to Drupal Development, can someone give me a bit more detail on how to go about getting this code into my site, what file to create or edit, what directory to drop it in, etc?
Thank you
- Jason
Comment #9
carlnewton CreditAttribution: carlnewton commentedI know this is very old, but I needed this code and the last question has gone unanswered.
Thanks for the code, Grant. Hopefully this will be put into the module eventually.
jalane81, to install this code as a module go to the /sites/all/modules/ directory and create /capatch
Within /capatch, create capatch.info with the following contents:
Then create capatch.module with the code above in it. Enable the newly created module.
Comment #10
carlnewton CreditAttribution: carlnewton commentedAdditionally, when using the code above, immediately after downloading a file, the next node to be loaded springs up the following error:
I've added an isset conditional:
Comment #11
carlnewton CreditAttribution: carlnewton commentedI needed this to be quickly accessible in a module format so figured I'd supply for easy installation for you guys. Drupal.org has renamed the tar.gz for security reasons, so you'll have to rename. The code is pretty much exactly as grantlucas provided, except with my fix in post #10.
Comment #12
DaPooch CreditAttribution: DaPooch commentedThis code is a good idea but I've found it to be problematic in two ways:
1. It doesn't account for images that may also be private and the module as is will render all private images inaccessible, or at least the ones shared with a node that may also have a private file attached to it.
2. It doesn't really account for the use case where a file can be attached to multiple nodes, some restricting access and others that don't. By default I believe it will default to restrict if any node has restricted access but I haven't fully tested this scenario. The problem really is if multiple nodes use the same file there's no easy way of knowing which one is placing the restriction on it.
Comment #13
davidpugh CreditAttribution: davidpugh commentedHello, I am having the same issue.
files in the private file system associated with content types that are not accessible by anonymous users (because that content type is restricted by content access) can be viewed by an anonymous user if the user knows the url of the file in the private file structure.
I'm using Drupal version 7.52, and content access 7.x-1.2-beta2.
I downloaded this module created by grantlucas and installed it.
It now restricts all private files from being viewed, even files in the private file structure that are associated with nodes that are viewable by anonymous.
I debugged with devel debug log module and found that the $file variable is always showing up as null.
ie:
if (isset($file)) {.....}
*The $file variable above is always null.
$file is not defined anywhere.
Any idea why this would be?
Comment #14
Isostar CreditAttribution: Isostar commentedThe content access module can even make files downloadable of nodes that were even not viewable without the module.
Examples:
- if permission 'view published content' is unchecked for anonymous users
- if an node is unpublished
In both cases the private files of the node are downloadable after activating the content access module (and rebuilding permissions)
Comment #15
Isostar CreditAttribution: Isostar commentedComment #16
Sherif Darwish CreditAttribution: Sherif Darwish commentedHi,
I tested the content access module and i still see this problem as critical one impacting one of my projects, if a file is marked as private and we do not have content access module installed then drupal will not allow access to this file. however after i installed the content access module i am able to access private files attached to nodes without any validation (i.e. anonymous users are able to access the files using its private url : http://domain.com/system/files/36479_0.m4a )
I tried going through content access module to check how the permissions are granted or denied for file access but it is taking me some time so i found this hook hook_file_download_access which can prevent access to file download based on user permission to the node where this file is attached
I tried it on my side and it worked this way, so when a private file is being downloaded drupal will check the user access to its parent node
I am not sure if this is the best way but i am open to enhance it or commit it to content access module
Comment #17
wipeout_dude CreditAttribution: wipeout_dude commentedCan anyone confirm if this bug is still present in the D8 version of the module?
Comment #18
markusa CreditAttribution: markusa commentedPing on this issue. Hard to see how this issue is not taken seriously....With 0 maintainer attention to this, makes one wonder what other problems lurking...
Is this the case for the D8 version?
Comment #19
cestmoi CreditAttribution: cestmoi commentedI confirm it's the case for the D8 version too !!!
Comment #20
zkrebs CreditAttribution: zkrebs commentedI'm considering this module for selling access through Drupal Commerce/Rules, but can't use it if there's a glaring security bug (we have private files on our site).
Comment #21
joshuasosa CreditAttribution: joshuasosa commentedHow does this issue get replicated?
I can view the node while logged in, and get access denied while logged out. I can download the file while logged in using the /system/files URL that's automatically added to the page, but get access denied when attempting to visit that file URL while logged out.
I tried with per-node access settings, making Basic page viewable by anonymous but unchecking anonymous from my specific node, and get the expected result. I also tried not unchecking the "view own page" for anonymous, but still get access denied for anonymous.
Comment #22
capysara CreditAttribution: capysara commentedI can’t recreate this either.
For anonymous users:
I also tried with access control for authenticated users of different roles:
Comment #23
presleyd CreditAttribution: presleyd commentedI can't reproduce this in D7 or D8 version. My attempts are the same as #22.
In addition, I tried the option listed in #14
Comment #24
mkindred CreditAttribution: mkindred commentedI cannot reproduce this in D7.
Steps:
Comment #25
gisleI am unable to reproduce this in any of the project's supported versions.
Below is a fairly detailed description of how I've tested both branches.
Branch 7.x-1.x-dev:
Branch 8.x-1.x-dev:
My testing confirms what is reported by the four latest comments:
The original report is from 2011 and I believe this has been fixed somewhere along the road from there, and that no patch is needed to fix this at this point.
I am moving to "Fixed" now. If someone disagree and still think this is an issue, please provide a detailed description of how to reproduce from a clean install. I'll continue to monitor this issue and will reopen if somebody produces evidence that this is still an open issue.