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

jonathanshaw created an issue. See original summary.

jonathanshaw’s picture

Status: Active » Postponed (maintainer needs more info)
Related issues: +#2785449: It's too easy to write entity queries with access checks that must not have them
jonathanshaw’s picture

Status: Postponed (maintainer needs more info) » Postponed
jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Issue summary: View changes
catch’s picture

Priority: Normal » Critical

These 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.

jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Issue summary: View changes
longwave’s picture

Status: Postponed » Active

Based 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.

jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Created #3201470: EntityQuery accessCheck: Cron functions should never check access as a proof of concept for fixing a set of these.

jonathanshaw’s picture

jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

jonathanshaw’s picture

Issue summary: View changes

I 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

jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Issue summary: View changes

core/modules/comment/src/CommentManager.php getCountNewComments is not buggy

jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

andypost’s picture

Only views plugins issue left in minors

jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

Issue summary: View changes
andypost’s picture

Status: Active » Fixed
catch’s picture

Adding 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.

jonathanshaw’s picture

Status: Fixed » Needs work

Unfortunately 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

jonathanshaw’s picture

Actual 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.

jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

jonathanshaw’s picture

jonathanshaw’s picture

Issue summary: View changes
jonathanshaw’s picture

Status: Needs work » Fixed

Thanks to @longwave. @catch and others, the reminaing cases got fixed.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

effulgentsia’s picture

Issue tags: +9.2.0 release notes

Should we mention this meta issue (or some of the specific child issues) in the 9.2 release notes? And/or a change record?

jonathanshaw’s picture

I 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.