Problem/Motivation
Drupal's private file access handling will grant access to the file to whoever has access to the entity where the field is attached. This means that a node with a file field will keep access to the node and the file in sync (granting access to the file if the user has access to the node, etc).
This is still true when using files attached to media entities, in the sense that Drupal will by default grant access to the file to users that can access the media entity. However, users may have the expectation that access is also inherited from the entity referencing the media items, which doesn't happen.
This could lead to a potentially misconfigured site, where users could think their assets are protected but they end up being exposed publicly. This mismatch in expectation has been brought up in several issues recently, such as:
#2904842: Make private file access handling respect the full entity reference chain
#2937642: Access to files attached via media entities should be ultimately controlled by the published state of related content
#2981131: Media Entity Pages Anonymous Permission
#2980424: "View media" grants permission on all private media files (no host entity check?)
While the real fix is being discussed in #2904842: Make private file access handling respect the full entity reference chain, this issue aims at reducing the confusion and making it explicit that Drupal does not do that out-of-the box, when using media entities instead of direct file fields.
Steps to reproduce:
Reference scenario (nodes with fields):
1) In a clean install, add a file field to a content type
2) When asked to configure the field storage, select "Private"
3) Create a node as unpublished, uploading a file to that field
4) As an anonymous user, try to reach directly the file URL
Result: Anonymous users do not have direct access to the file, if the node is unpublished.
"Problematic scenario" (nodes with media):
1) In a clean install with the Media module enabled, configure the "File" field on the "File" media type to use the "Private" file storage scheme
2) Add a media field (entity_reference) to a content type, allowing users to reference the "File" media type
3) Create a node as unpublished, uploading a file to that field
4) As an anonymous user, try to reach directly the file URL
Result: Anonymous users have direct access to the file, even though the node is unpublished.
Proposed resolution
Action 1:
Show some messages to the site builder to make that situation clear:
- When configuring a media source field to use the private filesystem

- When checking messages at the status report page

- In hook help text

Action 2:
Add some more detailed information about media access handling and possible misconfiguration scenarios in drupal.org documentation
- Created https://www.drupal.org/docs/8/core/modules/media/setting-up-private-acce... for that
Remaining tasks
- Review patch / Address feedback
- Complete documentation on https://www.drupal.org/docs/8/core/modules/media/setting-up-private-acce...
- Collect sign-off
- Commit
User interface changes
- New message(s) will appear to site builders in some contexts (see screenshots above)
API changes
None.
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #45 | 2984093-nr-bot.txt | 144 bytes | needs-review-queue-bot |
| #36 | 2984093_36.patch | 11.97 KB | vsujeetkumar |
| #30 | warning_field_ui_page.png | 176.12 KB | marcoscano |
| #30 | status_report_warning.png | 324.38 KB | marcoscano |
| #30 | help_page.png | 441.62 KB | marcoscano |
Issue fork drupal-2984093
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
marcoscanoThis is a re-upload of the patch in #2904842-20: Make private file access handling respect the full entity reference chain. Also moving over the comments from there:
- Created a placeholder documentation page for this at https://www.drupal.org/docs/8/core/modules/media/setting-up-private-acce... , we still need to figure out what to explain there, point to contrib solutions, etc.
- The warning is shown in both the status page and in the manage fields page, as shown in the screenshots below
- Devs can disable the warning with drush by executing
drush cset media.settings show_private_scheme_warning 0, and re-enable it back the same way by setting the flag to 1- Final wording might still need some tweaking
- We still need tests for this, but I was hoping to get a 👍 or 👎 on the approach before writing them
Warning on the fields page:
Warning on the status page:
Comment #3
marcoscanoComment #4
xjmI think that it makes a lot of sense to inform/warn users about this, because the mismatch in expectations can lead to unintended disclosures (even though the behavior is by design).
A couple thoughts about the current approach:
hook_help()text added to that route rather than a warning.Note that I didn't say "Media type(s)"; we should probably use
formatPlural()for that for better translation support.hook_help()about this, possibly just a short section that links the proposed handbook page. (Also let's at least get minimal content on that page before we commit this, since Media is stable and so it's covered by the docs gate.)Thanks! I think this is a really good step to straightening out the tangle of access expectations about Media.
Comment #5
marcoscano@xjm many thanks! That's very useful feedback!
1- Fixed, moved it to an info message
2- Fixed, although I have thoughts on this one. Some part of me tells me that the "normal text" will pass unnoticed, while the warning draws the attention of the site builder.
3 and 4- This is the tricky part. There could be a complex chain of relationships of usages, or even entities that are not being used anywhere, but could be used in the future, so identifying "what is affected by this" may become a complex process without a system that tracks entity relationships in Drupal natively (and which is part of the reason the fix is not in place in the first place...)
5- Tweaked the message a bit. Didn't add the entities that reference the media type because again, there could be several layers of relationships, and for example having a paragraph or a custom entity component exposed on this list may not always make sense for the site builder. But in this case it is not so hard to build up a list, if you think we should have it here, we can.
6- I'm not sure about this... Ideally, our warnings are clear enough for the site builder / developer that they will fix the issue during the development cycle, so end users (editors) would never need to be bothered by this. Even if they did, in most cases the editors do not have the means to solving the issue? (changing field storage, installing modules, etc)
7- Added a short section to the help. Any suggestion about what the documentation page should look like? Technically we "don't have" a solution, so I wonder what the best message is to have there at this point. I did start to play around possible solutions in a contrib module, but from there to have it as "the" recommended approach, I believe there's a good distance... Anything we could recommend apart from "you need to figure out a solution yourself" ?
8- 👍
This is what this round of adjustments look like:
On the field UI page:
On the status report:
On the hep page:
(Still needs tests so I'm not moving the issue status, but I hope we could be able to move forward with the discussion without them at this point)
Thanks again!
Comment #6
marcoscanoThis was discussed in the UX meeting today ( video ), the summary is:
Comment #7
marcoscanoWell, the final wording would still probably need UX sign-off, so I guess it's better just to leave the tag for now.
Comment #9
phenaproximaTRUE should be lowercase true. Also, can we rename this to show_private_file_warning? 'scheme' is a weird word in this context.
Can we adjust this: "...is configured to use private file storage"?
This seems like a good place to use array_filter(). Additionally, I think it'd be better to check if the source field item list is, or extends, FileFieldItemList rather than rely on a field type ID.
Nit: I think "Media items" should be lowercased to "media items".
This repeats code from hook_install(); seems like we should have a static method somewhere to determine this. How about a static method on the File source plugin to determine if a given media type is compatible with it?
Comment #10
marcoscano@phenaproxima thanks for reviewing!
I'm working on it.
Comment #11
marcoscano1- OK
2- OK
3- OK
4- OK
5- Do you feel strongly about this? It seems to me that we would be saving only a couple lines of code duplication, and having an extra method for that would actually increase maintenance burden. (Unless I'm missing what you suggest to abstract out).
Added a test for the new warning messages and the settings flag to dismiss it, and also updated the IS and added the screenshots there too.
Comment #12
marcoscanoNot sure why the tests are failing, in manual test it works... :/
Any insight on that will be appreciated.
Comment #13
phenaproximaLooks really damn good. Everything I found, to be honest, is relatively nitpicky.
Can we rephrase this a bit "...differently than files and images regarding restricted access" might read better as "...differently than files and images where restricted access is concerned."
So this is the second time in this patch that we have repeated the "check if this media type uses files" logic. Media Library also does this, which convinces me that this check needs to be a public static method of the File source plugin.
If this is a new field, $field->original might not be set, which will cause this code to fatal, no?
Let's just call $this->getSession()->reload() here, rather than repeat the URL.
Nit: Any chance of using Url::fromRoute() to generate the URL?
Comment #14
marcoscanoThis addresses all points in #13, thanks!
Comment #16
marcoscanoSmall improvement on the naming/documentation of the new helper method.
Comment #18
marcoscanoNot a good idea to rename the method and not update the calls to it...
Comment #20
phenaproximaNit: This can be one line:
$types_to_warn = array_filter($media_types, [File::class, 'hasFileSourceField']).Comment #22
wim leers:doc_urlRather than doing this in a presave hook, this should be done in a config subscriber. See #3017935: Media items should not be available at /media/{id} to users with 'view media' permission by default for an example.
Cache::invalidateTags(['rendered'])is that cleaner way :)But are you sure we actually need to invalidate this?
Based on the name, I'd expect
return $source_field_definition->getType() === 'file';But I get it; you want to make sure that
@FieldType=imageand other subclasses are also detected.So let's make that more clear, because it's a bit surprising.
Also, I don't think the fact that it uses a
@FieldType=filefield is the problem here, I think the problem is that it's referencing aFileentity. Wouldn't it be safer to check whether one of the target types isFile? Then it'd also work for https://www.drupal.org/project/dynamic_entity_reference.Comment #23
marcoscano@Wim Leers Thanks for reviewing!
This should address #22 and also the test failures.
Comment #24
marcoscanoComment #25
wim leersÜbernit: we usually call a variable containing a render array
$build.🎉
Übernit: can be chained.
Comment #26
marcoscanoThanks for the feedback!
Comment #27
wim leersÜbernit: small indentation problem here: the last 3 quoted lines have two leading spaces too many.
I was concerned that this warning doesn't look like a warning, because it's just help text on the page that is easily missed. But @marcoscano pointed out that this is exactly what was requested by @xjm, because it's a warning that cannot be acted upon/resolved. Tricky to make a decision here, but I get it.
This was my only remaining concern.
Comment #28
marcoscano#27.1: Ops, sorry I missed that
#27.2: yes, see #4.1
Thanks!
Comment #30
marcoscanoUpdated the IS screenshots with the most up-to-date text from the patch.
Comment #31
alexpottWe need an update path to add this for existing sites. Also I think in the update we should return text telling users that they have this situation in case they are unaware.
This doesn't really work for translatable strings. We should use an inline item list and render it.
An inline item list looks like:
Also requirements can be render arrays. See code in
system_requirements()I think this can be abbreviated to
Comment #34
xjmComment #36
vsujeetkumar commentedRe-roll patch created for 9.1.x
Comment #37
phenaproximaThis is certainly a critical issue for the completion of the Media Initiative, so I'm bumping the priority.
Comment #38
benjifisherUsability review
We looked at this issue at the #3173646: Drupal Usability Meeting 2020-09-29.
Generally, the messages seem clear. Of course, the new documentation page has to be completed.
I am removing the word "warning" from the issue summary.
The only message that seems to need some attention is the one on the help page:
Comment #41
anybodyI agree with #38 and as said in #37 this is still quite important for Drupal Security and Triaged Media Initiative. So should we incorporate the changes from #38 or is this to be discussed first?
Looking at security and priority we should get this more or simple "fix" in asap, shouldn't we?
Comment #45
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #46
anybody@benjifisher sorry to ask this 3 years later, but do you know which patch was reviewed? #36?
If it's just these wording changes, I'd create a MR against 10.1.x and push things forward here.
Sad to see that https://www.drupal.org/project/media_private_access has no Drupal 9/10 release, while this is still problematic.
Comment #49
grevil commentedI applied patch #36 manually on 10.1.x and changed the wording proposed in #38.
Please review!
Comment #50
anybodyThanks @Grevil! Just one wording change, then all points from #38 are addressed.
See my comment in GitLab. Or am I wrong?
Comment #51
grevil commentedComment #52
anybodyWell done! As all points from #38 have been addressed, I'm setting this RTBC for maintainers to have a look.
What about "Needs documentation updates" tag?
Also note #4.4 as possible followup. Do we need a discussion on that point?
I think it's most important to get this merged asap.
Comment #53
phenaproximaLooks like tests are failing on coding standards checks.
Comment #54
grevil commentedMy apologies, my dev environment is not suited for core issue... Should definitely fix that!
Edit: Will fix that tomorrow.