Managed files on a private file-system that do not have references from other entities can not be downloaded or viewed. Or styled using Drupal core's "image styles". This stems from lingering assumptions in Drupal 7 core that files are properties or meta data attached to other entities, instead of first class citizens (or entities) in their own right.

Specifically, this code in file_file_download() (an implementation of hook_file_download() in core's file.module) prevent access to the file. It was introduced in Drupal 7 in "#898036: Private images broken". And later extended to handle edge cases:

  // Stop processing if there are no references in order to avoid returning
  // headers for files controlled by other modules. Make an exception for
  // temporary files where the host entity has not yet been saved (for example,
  // an image preview on a node/add form) in which case, allow download by the
  // file's owner.
  if (empty($references) && ($file->status == FILE_STATUS_PERMANENT || $file->uid != $user->uid)) {
      return;
  }

Possible solutions

  • Drupal core: Removing that code appears to solve the problem. And in brief testing I could not reproduce the original bug that #898036 intended to fix. I have not yet tried reproducing the bug or it's fix on Drupal 8, nor rolled a patch or run simpletests. While this is desirable, a core patch is a long-winded process which likely won't help Media module and File entity move forward at their current momentum.
  • File Entity and/or Media module could implement it's own hook_file_download() or create a dummy entity with references to all files just for this case. But neither of those are clean solutions.
  • File Lock module implements a solution for another bug resulting from Drupal 7's assumptions about Files, where files that have become "orphaned" are deleted, when any entity referencing the file is updated, created or deleted.

    Conceptually, File Lock module should also solve the problem described here. However File Lock module solves the problem by adding a row to the file_usage table, while file_file_download() uses an EntityFieldQuery to look for entities that reference the file.

    File Lock module could be changed to handle both cases via a dummy entity. This is cleaner than doing so inside File Entity or Media modules.

  • On that note, Drupal core's file_file_download() could instead use the file_usage table which would be simpler, more performant and make it more extensible in cases like this. However that would also be a core patch and would still not help to fix Drupal core's broken assumptions about Files.
  • Any other ideas?

Similar: #1351906: Importing image fails on private file system..

#1351906 may be duplicate but the subject suggests that the import fails. While here the issue is downloading/viewing files that were successfully uploaded (or imported). I expect that the same issue will occur with imported images as they will also be "orphaned" as per Drupal 7 core's assumptions. I have not tested that case.

Also; I am not sure if the solution to this problem is best discussed in File Entity module's issue queue, or that of Media module, Drupal 7 or 8 core, possibly File Lock module's or a combination of the above. That probably depends on the solution(s) that are agreed to be most appropriate.

CommentFileSizeAuthor
#2 eight.patch1003 bytesBevan
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

gollyg’s picture

At first blush, this doesn't seem to explicitly prevent access to the file, it merely says that it doesn't know what to do with it, as it is not being managed by the file/file field module. It would need to return -1 to prevent access.

Which seems in the spirit of hook_file_download. So wouldn't implementing this hook in file_entity make sense? Or even in modules that use file_entity (obviously media springs to mind), so that we aren't making assumptions about how the file is being managed.

More generally I agree that this is all a bit of a mess, and would love to see access control generalised out through an entity_access_api (usage is not a concept unique to files - any entity can reference any other entity, and an api to manage this would be great. eg http://drupal.org/node/777578

Bevan’s picture

Project: File Entity (fieldable files) » Drupal core
Version: 7.x-2.x-dev » 8.x-dev
Component: Code » file system
Status: Active » Needs review
FileSize
1003 bytes

This patch fixes the bug by removing code that was added in #898036: Private images broken. And later extended to handle edge cases.

I tested both with current 8.x and 7.x git branches of Drupal core. And I tested each version both with and without the attached patch. The original bug reported in #898036 was not reproducible in any of the four scenarios. The bug described in this ticket was reproducible in both 7.x and 8.x without the patch, but was not reproducible with the patch.

The test method was not comprehensive but does make a good argument for removing the code that was introduce in #898036. Further review, testing and simpletests are required. The test method was;

Starting with a fresh "Standard" install;

  1. admin/config/media/file-system: Configure a "Private file system path".
  2. admin/config/media/file-system: Make "Private local files served by Drupal." the "Default download method".
    • This is necessary so that styled (aka "imagecached") images are stored in and served from the private files directory.
    • This option only becomes available after configuring the "Private file system path" in step 1.
  3. admin/structure/types/manage/article/fields/field_image: Configure the "Upload destination" as "Private files".
  4. node/add/article: Set a title, upload an image file to the "Image" field and save the node.
  5. Browser: Open the image directly in another browser tab. E.g. by right-click, "Open Image in New Tab" in Chrome.
  6. Browser: Delete styles/large/private/ from the image's URL and open the new shorter URL in a new tab (E.g. shift+enter in Chrome)
  7. Note: The image displays in all three tabs, as expected.
  8. Database: Delete the row in field_data_field_image that corresponds to the recently uploaded file. E.g. DELETE FROM {field_data_field_image} WHERE entity_type = 'node' AND entity_id = 2 where the node's NID is 2.
    • This is a hack to create the scenario of an orphaned file, such as a file added via the File Entity module instead of via a node form or user form. Although it is a hack, it reproduces a valid scenario of "Files as first-class citizens" in Drupal. (First class citizens should be valid entities regardless of their "orphan-status".)
  9. Refresh the last of the three tabs opened above; the original file with the shorter URL:
    • Expected behaviour: The image is accessible.
    • Actual behaviour (without the patch): Drupal renders a 403 "Access Denied" page.
  10. Refresh the other two tabs and note that the image is still accessible.
  11. Delete the styled (imagecached) image in styles/large/private/.
  12. Refresh the other two tabs again.
    • Expected behaviour: The styled image is accessible.
    • Actual behaviour (without the patch): Drupal renders a 403 "Access Denied" page.
Bevan’s picture

Status: Needs review » Needs work

The last submitted patch, eight.patch, failed testing.

Bevan’s picture

The test that failed was "Confirmed that access is denied for the file without the needed permission." (FilePrivateTestCase->testPrivateFile()).

That failed because this change makes all files always accessible. The code that the patch removes is keeps private files private, without explicitly denying access to them. This bug is more complicated and raises bigger questions about how file access permissions should be managed.

Bevan’s picture

A related bug with private file systems that applies to files on taxonomy terms is #1423750: Private files on Taxonomy Term fields are not displayed.

Bevan’s picture

Issue summary: View changes

Adding tags around the File Lock solution to make it more consistent and more detail about the alternate Drupal core solution.

andros’s picture

Using D7 I have noticed I can't access any file that is not some how connected to a node,
this means:
If private file system is set as default:

  • can't access the logo of the theme
  • can't access sample images from the styles module config/media/image-styles

and

  • can't access default images (files?) in fields, if the field is set to private file system

I have searched for this for some time now. Is there relay no solution for this?
I have tested this on different Servers, with different installations and with fresh installs, allays the same.

Meaning: Drupal comes with a broken private file system?

deanflory’s picture

Andros, I too can't access sample images from the Image Styles previews and I'm using a private file system. I can however see the logo of the them and default images on fields. I too am amazed this hasn't been fixed yet. Everybody is too busy working on Drupal 8 and has almost completely neglected Drupal 7. At least with D6 enough module maintainers kept up their modules, not really the case for the majority in D7. </gripe>

Bevan’s picture

Andros; yes

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

meezaan’s picture

Has there been any update on this issue?

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.