In #2304969: Port private files access bypass from SA-CORE-2014-003, a new entity constraint was added to File and Image field types which ensures that a user can only add a reference to a file/image that they have access to.
This constraint is only supposed to verify access of the referenced file if it's a new/changed reference, meaning the user changed the reference from what it was to something else. However there is a bug in this code that forces the check to occur every time even if the reference didn't change.
I came across this bug when trying to add custom role-based view access control on media entities with private files:
- Create a media entity "Private Document" that has a private file schema
- Add a hook_media_access implementation that forbids "view" operation on entities of that media bundle to anyone without special role
- Add a new "Private Document" entity and upload a file and save
- Now go to edit the same entity, and try saving again. You get an error "You do not have access to the referenced entity (%type: %id)."
The problem occurs because the ReferenceAccessConstraint is now checking to ensure that the user has "view" access to the referenced private file on the file field. Well, since access of private file fields is delegated to the entity that references it, access is denied because the user that's editing the entity doesn't have that special role from step 2 above.