Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
_node_access_rebuild_batch_operation() is using entity queries that do access checks. Just after all grants are deleted. This means that only users with bypass node access
or user 1 can rebuild the grants. Which prevents a hook_update_N of doing this. And potentially any user with the permission administer site configuration
but not that permission can complete break node access.
Proposed resolution
Make the entity queries ignore node access.
Remaining tasks
User interface changes
None
API changes
None
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#13 | 2785155-12.patch | 6.98 KB | alexpott |
#13 | 6-12-interdiff.txt | 6.36 KB | alexpott |
#13 | 2785155-12.test-only.patch | 5.22 KB | alexpott |
#6 | 2785155-6.patch | 1.41 KB | alexpott |
#6 | 4-6-interdiff.txt | 543 bytes | alexpott |
Comments
Comment #2
alexpottThe D7 version of this uses db_query() and does not suffer from this.
Comment #3
alexpottComment #4
alexpottThis is quite close to a critical because if a user did this there site would have plenty of access denied.
Comment #5
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThere is an
->accessCheck(FALSE)
just a few lines below :)Comment #6
alexpottSo it's just the count query that is wrong.
Comment #8
alexpottPromoting to critical because if you run the node access rebuild without the bypass node access permission or being user 1 the first thing it does is delete all node access records. And then it attempts to write them. Given that the max could be 0 this means only 20 nodes will get processed. Leaving all the other nodes without node access records. Nodes without node access records with be inaccessible so there's not a security problem but the only way to fix it is to get a user with the correct permissions to re-run the rebuild. However, given that there is no indication that something has gone horribly wrong people might not guess the correct work around.
Comment #9
dawehnerBy reading
\Drupal\node\Tests\NodeAccessRebuildNodeGrantsTest::testNodeAccessRebuildNodeGrants
we should IMHO ensure that we got grants for everything we expect. This test coverage feels really loose.Comment #10
alexpott@dawehner well it is better than \Drupal\node\Tests\NodeAccessRebuildTest which doesn't really test anything.
Comment #11
alexpott@dawehner but I agree we need to have more than 20 nodes and nodes which the user running the test can't access.
Comment #12
dawehnerWait we don't trust our messages?
Comment #13
alexpottExpanded the test coverage.
Comment #14
alexpottI've removed this test because it is totally not useful. It is duplicating what is in the other test without really test anything at all. Rebuilding node access without a node access module is tested by \Drupal\node\Tests\NodeAccessRebuildNodeGrantsTest::testNodeAccessRebuildNoAccessModules() and it does it better. Also this test should have caught this bug because the user that rebuilds node access doesn't have permissions to bypass node access. But there are no nodes and there are no node access modules installed :(
Comment #16
alexpottDrupalCI error - something about going offline
Comment #23
alexpottComment #24
catchNice find. Patch looks great to me.
Comment #25
Berdir+1, looks good to me as well.
Related issue: #2671916: node_access_rebuild() will never work after since entityQuery has now accessCheck default set to true and the grants are deleted beforehand
not sure why we didn't cover this back then.
Comment #26
catchCommitted/pushed to all three 8.x branches, thanks!