Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 295818

[meta] Fix undesirable access checking on entity query usages

$
0
0

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

(in possible order of impact)

  • core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldValueValidator.php validate
  • core/modules/migrate/src/Plugin/migrate/process/MakeUniqueEntityField.php exists
  • core/modules/field_ui/src/Form/FieldStorageConfigEditForm.php validateCardinality
  • core/modules/layout_builder/src/Form/LayoutBuilderEntityViewDisplayForm hasOverrides
  • core/modules/workspaces/src/WorkspacePublisher.php getDifferringRevisionIdsOnTarget
  • core/modules/block_content/src/BlockContentUuidLookup.php resolveCacheMiss
  • core/modules/content_moderation/src/Entity/ContentModerationState.php loadFromModeratedEntity
  • core/modules/menu_link_content/src/Plugin/Deriver/MenuLinkContentDeriver.php getDerivativeDefinitions

Minor bugs

#3201470: EntityQuery accessCheck: Cron functions should never check access

#3201714: EntityQuery accessCheck: data cleanup should never care about the current user

Entity type delete forms should warn about any content at risk even if deleting user lacks access:
- core/modules/node/src/Form/NodeTypeDeleteConfirm.php buildForm
- core/modules/block_content/src/Form/BlockContentTypeDeleteForm.php buildForm
- core/modules/comment/src/Form/CommentTypeDeleteForm.php buildForm
- core/modules/media/src/Form/MediaTypeDeleteConfirmForm.php buildForm

titleQuery() usually uses loadMultiple() so should not check access:
- core/modules/file/src/Plugin/views/argument/Fid.php titleQuery
- core/modules/node/src/Plugin/views/argument/Vid.php titleQuery

Others:
- core/modules/media/src/Access/MediaRevisionAccessCheck.php countDefaultLanguageRevisions
- core/modules/aggregator/ MANY
- core/modules/menu_ui/menu_ui.module
- core/modules/tracker/tracker.module _tracker_remove
- core/modules/user/user.api.php hook_user_cancel
- core/modules/user/user.module user_is_blocked

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.

Unsure

Are these bugs or not?
- core/modules/comment/src/CommentManager.php getCountNewComments
- core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php loadContentModerationStateRevision

No fix needed

Places where accessCheck(TRUE) was added in #2785449: It's too easy to write entity queries with access checks that must not have them and it is the correct behavior.

- core/lib/Drupal/Core/Entity/EntityListBuilder.php
- core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php
- core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php
- core/lib/Drupal/Core/Menu/DefaultMenuLinkTreeManipulators.php
- core/modules/comment/src/Form/CommentAdminOverview.php
- core/modules/media/src/MediaListBuilder.php
- core/modules/node/src/Controller/NodeController.php
- core/modules/path/src/PathAliasListBuilder.php
- core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
- core/modules/taxonomy/taxonomy.tokens.inc
- core/modules/user/src/UserListBuilder.php

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.


Viewing all articles
Browse latest Browse all 295818

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>