Problem/Motivation
#2785449: It's too easy to write entity queries with access checks that must not have them required all usages of entity queries to include a call the the accessCheck() method. To implement this, all entity query usages in Drupal core that did not previously specify access explicitly added an explicit accessCheck(TRUE) call because TRUE was the previous implicit default behavior if accessCheck() was not called.
This was done to keep the issue simple, so that the behavior of no query in core was changed. However, in a large number of cases where accessCheck(TRUE) was added, the query probably should NOT be checking access and this should now be changed to accessCheck(FALSE).
The purpose of this meta issue is to keep track of the changes from #2785449: It's too easy to write entity queries with access checks that must not have them that have been reviewed and the issues that have been created to handle necessary fixes identified by that. These can be divided into the three broad categories below.
Significant bugs
#3202125: EntityQuery accessCheck: unique value validation should not be access sensitive
#3202440: [backport] EntityQuery accessCheck: field ui cardinality validation should not be access sensitive
#3203596: EntityQuery accessCheck: workspacePublisher is wrongly access sensitive
Minor bugs
#3203401: EntityQuery accessCheck: LayoutBuilderEntityViewDisplayForm hasOverrides()
#3203625: EntityQuery accessCheck: BlockContentUuidLookup should no be access sensitive
#3201470: EntityQuery accessCheck: Cron functions should never check access
#3201714: EntityQuery accessCheck: data cleanup should never care about the current user
#3202040: EntityQuery accessCheck: bundle delete forms should warn of content at risk regardless of access
#3202052: EntityQuery accessCheck: Views argument plugin ::titleQuery() should not be access sensitive
#3202107: EntityQuery accessCheck: _tracker_remove() updating should not be access sensitive
#3203366: EntityQuery accessCheck: user_is_blocked() should not be access sensitive
#3203369: EntityQuery accessCheck: aggregator module
#3203809: EntityQuery accessCheck: ContentModerationState queries should not be access sensitive
#3204138: EntityQuery accessCheck: MenuLinkContentDeriver::getDerivativeDefinitions should not be access sensitive
#3204140: EntityQuery accessCheck: menu_ui_get_menu_link_defaults() should not be access sensitive
#3204389: EntityQuery accessCheck: MediaRevisionAccessCheck::countDefaultLanguageRevisions should not check access
#3207654: EntityQuery accessCheck: more aggregator fixes
#3208265: EntityQuery accessCheck: comment_user_predelete() should not check access
#3208266: EntityQuery accessCheck: installation code should not check entity access
#3208267: EntityQuery accessCheck: InlineBlockEntityOperations should not check access
Trivial changes to tests
Most of the time in tests the intention is not to test access, but it doesn't matter whether access is checked or not. In these case we should set to FALSE in order to keep the intention of the test clear, but obviously no additional test coverage is needed. Theses cases can all be handled en masse in a single issue:
#3204163: EntityQuery accessCheck: tests should not check access unless relevant
#3207961: EntityQuery accessCheck: additional cases where accessCheck needs specifying
No fix needed
Places where accessCheck(TRUE) is the correct behavior:
#3204419: EntityQuery accessCheck: always specifiy accessCheck, don't rely on the default
#3207477: EntityQuery accessCheck: taxonomy storage helper queries should specifiy access checking
#3207961: EntityQuery accessCheck: additional cases where accessCheck needs specifying
Test coverage
As explained by @catch in #3201470: EntityQuery accessCheck: Cron functions should never check access:
- we have a really bad design pattern with entity queries, where it's very easy to create them without specifiying accessCheck(FALSE) and forgetting that this means that the returned entities are only those accessible to the current user
- the consequences of this kind of bug can be subtle, leading to logic that looks impeccable but fails in puzzling ways, or works in development but then starts showing up for some users on production
- this leads to many undiscovered bugs across core, contrib and custom code, and huge amounts of debugging time
- we want to specify the accessCheck on all entity queries in core, before we deprecate not specifying the accessCheck and move towards ending the pain in contrib and custom code.
- this requires us to fix all the core bugs around this, the places where core is currently not specifying accessCheck() leading to TRUE being assumed but actually FALSE is correct.
- all of these bugs are trivial to fix, and many of them are highly theoretical and very rare in real-life usage
- if we require test coverage for every single one of these bugs, they will probably proliferate faster than we can fix them, and we will never be able to do the deprecation and cut off the problem at the root
- therefore while test coverage is still required for these bugs when they involve significant breaches of data integrity that can occur in response to simple installing a node acess module, it is not always required where the real-life risk of occurence is much less.
Comments
Comment #2
jonathanshawComment #3
jonathanshawComment #4
jonathanshawComment #5
jonathanshawComment #6
jonathanshawComment #7
jonathanshawComment #8
jonathanshawComment #9
jonathanshawComment #10
catchThese are all critical data-integrity bugs, although in practice it'll only be an actual bug on a site when it's nodes being queried and there's a node access module installed, bumping priority.
Comment #11
jonathanshawComment #12
jonathanshawComment #13
jonathanshawComment #14
longwaveBased on discussion in #2785449: It's too easy to write entity queries with access checks that must not have them I don't think this needs to be postponed now we have started identifying cases, I think we can start creating child issues and picking them off if anyone wants to do so.
Comment #15
jonathanshawComment #16
jonathanshawCreated #3201470: EntityQuery accessCheck: Cron functions should never check access as a proof of concept for fixing a set of these.
Comment #17
jonathanshawAnother child created: #3201714: EntityQuery accessCheck: data cleanup should never care about the current user
Comment #18
jonathanshawComment #19
jonathanshawAnother child created: #3202040: EntityQuery accessCheck: bundle delete forms should warn of content at risk regardless of access.
Comment #20
jonathanshawComment #21
jonathanshawAnother child created: #3202052: EntityQuery accessCheck: Views argument plugin ::titleQuery() should not be access sensitive
Comment #22
jonathanshawAnother child created: #3202107: EntityQuery accessCheck: _tracker_remove() updating should not be access sensitive
Comment #23
jonathanshawAnother child created: #3202125: EntityQuery accessCheck: unique value validation should not be access sensitive
Comment #24
jonathanshawAnother child created: #3202440: [backport] EntityQuery accessCheck: field ui cardinality validation should not be access sensitive
Comment #25
jonathanshawAnother child created: #3203366: EntityQuery accessCheck: user_is_blocked() should not be access sensitive
Comment #26
jonathanshawAnother child created: #3203369: EntityQuery accessCheck: aggregator module
Comment #27
jonathanshawAnother child created: #3203401: EntityQuery accessCheck: LayoutBuilderEntityViewDisplayForm hasOverrides()
Comment #28
jonathanshawComment #29
jonathanshawTwo children created:
#3203625: EntityQuery accessCheck: BlockContentUuidLookup should no be access sensitive
#3203596: EntityQuery accessCheck: workspacePublisher is wrongly access sensitive
Comment #30
jonathanshawAnother child created: #3203809: EntityQuery accessCheck: ContentModerationState queries should not be access sensitive
Comment #31
jonathanshawI expanded the scope of #3203809: EntityQuery accessCheck: ContentModerationState queries should not be access sensitive to include core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php loadContentModerationStateRevision
Comment #32
jonathanshawAnother child created: #3204138: EntityQuery accessCheck: MenuLinkContentDeriver::getDerivativeDefinitions should not be access sensitive
Comment #33
jonathanshawAnother child created #3204140: EntityQuery accessCheck: menu_ui_get_menu_link_defaults() should not be access sensitive
Comment #34
jonathanshawComment #35
jonathanshawcore/modules/comment/src/CommentManager.php getCountNewComments is not buggy
Comment #36
jonathanshawAnother child created: #3204163: EntityQuery accessCheck: tests should not check access unless relevant
Comment #37
jonathanshawAnother child created: #3204389: EntityQuery accessCheck: MediaRevisionAccessCheck::countDefaultLanguageRevisions should not check access
Comment #38
jonathanshawAnother child created: #3204419: EntityQuery accessCheck: always specifiy accessCheck, don't rely on the default.
Comment #39
andypostOnly views plugins issue left in minors
Comment #40
jonathanshawAll work is now completed, and only 4 issues are not yet committed.
The following issues are simple to review:
#3202125: EntityQuery accessCheck: unique value validation should not be access sensitive
#3204163: EntityQuery accessCheck: tests should not check access unless relevant
#3204419: EntityQuery accessCheck: always specifiy accessCheck, don't rely on the default
The views plugin issue needs someone to answer an obscure policy question:
#3202052: EntityQuery accessCheck: Views argument plugin ::titleQuery() should not be access sensitive
Comment #41
jonathanshawAnother child created #3207477: EntityQuery accessCheck: taxonomy storage helper queries should specifiy access checking
Comment #42
jonathanshawAnother child created: #3207654: EntityQuery accessCheck: more aggregator fixes
Comment #43
jonathanshawComment #44
andypostI find this fixed, the remaining issue unblocked #2785449: It's too easy to write entity queries with access checks that must not have them
Comment #45
catchAdding some issue shepherding credit, amazing to see this fixed after I opened two duplicate issues in the queue and ignored both of them for years.
Comment #46
jonathanshawUnfortunately testing #2785449: It's too easy to write entity queries with access checks that must not have them has thrown up another 11 cases so I'm reopening this. Probably I missed a few, maybe some are because the drop is always moving ...
BookNavigationBlock
BlockContentListBuilder
DefaultSelection
workspaces EntityQuery
InlineBlockEntityOperations
comment_user_predelete
demo_umami_set_user_passwords
ContentEntityChangedTest
EntityQueryAggregateTest::testAggregation
EntityQueryTest::testCaseSensitivity
FieldableEntityDefinitionUpdateTest
Comment #47
jonathanshawActual bugs that need their own issues:
- comment_user_predelete
- workspaces_install & demo_umami_set_users_passwords
- InlineBlockEntityOperations
InlineBlockEntityOperations is a difficult one, it's not clear whether access checking is right or not.
The rest are handled in #3207961: EntityQuery accessCheck: additional cases where accessCheck needs specifying which is ready for review.
Comment #48
jonathanshawComment #49
jonathanshawAnother child created: #3208265: EntityQuery accessCheck: comment_user_predelete() should not check access.
Comment #50
jonathanshawAnother child created #3208266: EntityQuery accessCheck: installation code should not check entity access
Comment #51
jonathanshawAnother child created: #3208267: EntityQuery accessCheck: InlineBlockEntityOperations should not check access. That's the last one I know of.
Comment #52
jonathanshawThanks to @longwave. @catch and others, the reminaing cases got fixed.
Comment #54
effulgentsia commentedShould we mention this meta issue (or some of the specific child issues) in the 9.2 release notes? And/or a change record?
Comment #55
jonathanshawI don't believe so, mostly what's addressed here is trivial. #2785449: It's too easy to write entity queries with access checks that must not have them is more significant, but it simply generates a deprecation error so it might not make sense to put it in release notes.