Problem/Motivation

Symptom:

After saving an existing node or other entity, further access checks on that entity are incorrect for the remainder of the request.

Occurs more often when you have some custom access logic in hook_node_access(), hook_node_access_record(), hook_entity_access(), etc.

NOTE: This only happens with subsequent access checks within the same request.

Problem:

EntityAccessControlHandler statically caches calls to ::access(). There appears to be no invalidation of that cache when an entity is updated.

Steps to reproduce:

See patch with test.

Proposed resolution

Invalidate the static access cache (EntityAccessControlHandler::$accessCache) for an entity when the entity is updated.

It's not clear how/where that invalidation should happen.

Workaround:

Manually invalidate the entire static cache before subsequent access checks.

Drupal::entityTypeManager()->getAccessControlHandler('ENTITY_TYPE')->resetCache();

This can incur a performance hit since it resets the cache for ALL access checks.

Comments

milesw created an issue. See original summary.

milesw’s picture

This patch contains a test that reproduces the issue.

milesw’s picture

StatusFileSize
new3.83 KB

Here is a patch to use hashes instead of UUIDs as cache keys. Could not find a decent way to invalidate the cache upon entities being saved, so this seems like a decent alternative. Test from original patch is included.

milesw’s picture

Status: Active » Needs review

Changing status.

dawehner’s picture

+++ b/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php
@@ -180,6 +181,19 @@ protected function getCache($cid, $operation, $langcode, AccountInterface $accou
+   */
+  protected function getCacheId(EntityInterface $entity) {
+    return hash('sha256', serialize($entity->toArray()));
+  }

It would be really nice to document why we need all the values here. I could imagine that calling $entity->toArray() is quite expensive actually

larowlan’s picture

I agree with @dawehner

milesw’s picture

Status: Needs review » Needs work

Thanks for reviewing @dawehner. You're right, $entity->toArray() is probably too expensive to use there. Especially since it includes computed properties.

For the sake of performance, hashing entities is probably a bad approach here. Access checks can be called many, many times.

I'll investigate other possibilities, but it would be nice to get input from others more familiar with the entity system.

mlhess’s picture

mlhess’s picture

dawehner’s picture

I wonder whether it would be easier to key by $uuid, $revision_id, $langcode, $changed_time

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jhedstrom’s picture

Status: Needs work » Needs review
StatusFileSize
new925 bytes
new4.13 KB

This changes to utilize the cache keys mentioned by @dawehner. However, since the test entity isn't setting a new revision (id is coming back null), and doesn't implement EntityChangedInterface, the cache key doesn't change on save, making the test fail. This would resolve the issue for entities implementing those 2 interfaces...

Status: Needs review » Needs work

The last submitted patch, 12: 2834344-12.patch, failed testing.

jhedstrom’s picture

Status: Needs work » Needs review
StatusFileSize
new1.29 KB
new4.52 KB

This has the tests green. Since the getCacheId method could be overridden by entity types that do not implement changed or revisions, that could be customized as needed for other types...

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

This issue is being reviewed by the kind folks in Slack, #need-reveiw-queue. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge require as a guide.

Wonder if this is still an issue with the changes from this commit. https://git.drupalcode.org/project/drupal/-/commit/11ef44a7f767000930a25...

Sorry couldn't find the ticket for this

The current patch no longer applies but am wondering if it's been resolved.

Please do not just reroll till it's been confirmed still an issue.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs work » Postponed (maintainer needs more info)

Per #26

smustgrave’s picture

wanted to bump 1 more time before closing.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.