Problem/Motivation

The validator runs a query to find existing entities with the given unique field, but does not include ->accessCheck(FALSE). If you use this with an entity that relies on query alters, for example through entity.module's default implementation, existing entities might not be found.

Steps to reproduce

Proposed resolution

Exclude the query from access checks and add test coverage.

Remaining tasks

None.

User interface changes

None.

API changes

UniqueFieldValueValidator will no longer depend on the current user's access.

Data model changes

None.

Release notes snippet

Previously, the UniqueFieldConstraint was validated based on the current user's access, which could create critical data integrity problems if the same field value already existed on an entity the current user could not acccess. To resolve this data integrity problem, validation of the UniqueFieldConstraint will no longer depend on the current user's access.

In rare cases, this can cause entities that were already saved with corrupt data to become impossible to edit through the user interface. In such a case, developer intervention will be required to set the field to a valid value programatically using the Entity Field API.

CommentFileSizeAuthor
#17 3171047.patch4.06 KBcatch

Issue fork drupal-3171047

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Berdir created an issue. See original summary.

larowlan’s picture

we're likely to need some sort of integrity check / hook_requirements message here to warn that 'field x has integrity issue, required unique values, but has duplicates for {} in entities {}'

berdir’s picture

I fear so, but that's going to be pretty slow to calculate, well need to find all field definitions with a unique field constraint and then run an aggregate query on those entity types to find duplicates. Not sure if that's something that should run by default and every time you visit the status page. Maybe that could be done in a small contrib module instead and explain it in a change notice? This very likely only affects site with special entity types.

larowlan’s picture

There was talk in an update critical about adding a data-integrity checker to core. I think the example was a comment with a missing comment-type field or similar that was causing updates to fail. I guess this would fit in that.

But you're right, too slow for hook_requirements

catch’s picture

For critical upgrade path issues we've added those to hook_requirements('update') - but those would only run for schemas below a certain version, not every time you run updates.

#3056543: taxonomy_post_update_make_taxonomy_term_revisionable() and the menu link content equivalent fail when entities have no default translation and similar issues are where this sort of thing came up.

I could see putting this in hook_requirements('update'), showing a warning (not an error), and setting a state key so it doesn't run again, but to me feels like it could be a spin-off issue - existing sites will already have the problem, whereas the patch here fixes it for sites that don't have it yet too.

hchonov’s picture

but to me feels like it could be a spin-off issue - existing sites will already have the problem, whereas the patch here fixes it for sites that don't have it yet too.

Then does it really make sense to add code only to warn existing sites? What about an update that will search for such cases and just write a log message?

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.

jonathanshaw’s picture

Title: Entity query in UniqueFieldValueValidator must disable access checking » UniqueFieldValueValidator may have left non-unique values in database

This is getting fixed in #3202125: EntityQuery accessCheck: unique value validation should not be access sensitive. Let's repurpose this issue to be a follow-up discussing how to warn existing sites that suffered from the bug.

berdir’s picture

Can we do that? By fixing the bug, we might break the ability to save these then on existing sites, and depending on how it is used, it might or might not be easy to fix it. Unique-ness might be validated on a field that can't be changed afterwards?

jonathanshaw’s picture

Title: UniqueFieldValueValidator may have left non-unique values in database » Entity query in UniqueFieldValueValidator must not use access checking
Priority: Normal » Critical

We decided in #3202125: EntityQuery accessCheck: unique value validation should not be access sensitive to make the bug explicit there in order to unblock that issue's parent, but not to actually fix it. And @catch asked for the fix - this issue - to be critical (as it's a data integrity issue).

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.

stephencamilo’s picture

Status: Active » Closed (won't fix)
larowlan’s picture

Status: Closed (won't fix) » Active
mradcliffe’s picture

I added the Portland2022 tag. I also added the Needs issue summary update to maybe bring in some of the info in the issue linked in comment #10 (if necessary).

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.

catch’s picture

Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new4.06 KB

Here's a patch that brings back the bugfix + test coverage from #3202125: EntityQuery accessCheck: unique value validation should not be access sensitive.

@Berdir:

Can we do that? By fixing the bug, we might break the ability to save these then on existing sites, and depending on how it is used, it might or might not be easy to fix it. Unique-ness might be validated on a field that can't be changed afterwards?

This feels like the same as any other validation tightening, we had it with email validator too, and I don't think it should stop us fixing the bug - although we should do so only a minor release for this reason.

jonathanshaw’s picture

@catch what's your position on warning existing sites as discussed #2 - #9 ?

catch’s picture

@jonathanshaw as discussed it's going to be too expensive for hook_requirements(), and we don't really have anywhere else to put it, so I'm not sure it's worth the effort for what is quite a specific situation. It's not the update that will fail, but only validation in cases that should have failed validation anyway.

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.

mxr576’s picture

How about doing an iterative approach, like...

Iteration 1:
1. On newly created instances that are not installed from config, use a different validator behind UniqueFieldConstraint than on the others
2. Create a new _real_ \Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValidator
3. Mark \Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator as deprecated and remove it in Drupal 11

Iteration 2 (Drupal 11)
1. Provide a tool (script?) for analyzing the database before the Drupal 11 upgrade for non-unique values.
2. Suggest ways to fix none unique values before Drupal 11 upgrade. At worst suggest, suggest using the original "unique-ish" validator from Drupal 10 as custom code on a project.

jonathanshaw’s picture

Status: Needs review » Reviewed & tested by the community

Per #17 we have a release manager saying the fix in #17 here is good as is. I agree that it's better to fix this critical issue now than let it persist forever because a better but slightly complex solution is possible.

The patch is good, so RTBC.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 17: 3171047.patch, failed testing. View results

jonathanshaw’s picture

+++ b/core/tests/Drupal/KernelTests/Core/Validation/UniqueFieldConstraintTest.php
@@ -112,4 +113,38 @@ public function providerTestEntityWithStringIdWithViolation() {
+      '@field_name' => 'name',

This needs to be 'Name' to fix the test failure.

rpayanm made their first commit to this issue’s fork.

rpayanm’s picture

Status: Needs work » Needs review
jonathanshaw’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
Issue tags: -Novice, -Needs issue summary update

Thanks @rpayanm.

Added change record, updated IS.

RTBC for reasons gived in #22.

xjm’s picture

Just confirmed that the MR opened in #26 fixes #24, thanks @rpayanm.

xjm’s picture

Hiding the failing patch.

xjm’s picture

Issue summary: View changes

Making a few changes to the release note:

  1. Linking the change record.
  2. Adding a sentence that explains how to fix "impossible to edit" entities, because otherwise the release note is terrifying. There was already a sentence about this in the CR that we can repurpose.
  3. Adding a sentence before that about why we are making this change, because if you don't understand the data integrity aspect and all you know is that it might make some entities impossible to edit, that sounds like a really bad idea.

Adding credit for the helpful reviews and discussion on the issue. I read all of them to understand the implications of this change, why we weren't providing some sort of update hook, etc. Even #21, which turned out not to be the direction we took, presented a good alternate course of action to compare it to.

xjm’s picture

Status: Reviewed & tested by the community » Needs work

I read over #3200985: [meta] Fix undesirable access checking on entity query usages and #3202125: EntityQuery accessCheck: unique value validation should not be access sensitive as well as this issue, and agree with going forward with this solution.

There are a couple small fixes I think we should make for the test. I left suggestions on the MR.

jonathanshaw’s picture

Status: Needs work » Reviewed & tested by the community

Thanks Rolando for the fix, and @xjm for the careful review. The changes to the release note seems great.

  • xjm committed 59e21652 on 10.1.x
    Issue #3171047 by rpayanm, catch, jonathanshaw, Berdir, xjm, larowlan,...
xjm’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +10.1.0 release highlights

Thanks everyone! I had to fix a couple of small whitespace errors (not sure why it didn't get retested when the suggestions were applied.) Other than that it was fine, though.

On account of the potential editing bug for users, we'll keep this bugfix limited to 10.1.x only. I considered backporting it because of the data integrity aspects, but the fact is that it's been broken for a long time whereas the corrupt entities not being editable would be a new problem, so let's keep this minor-only as a disruptive bugfix.

Tagged for the 10.1.0 release notes, and published the change record. Thanks!

mondrake’s picture

Status: Fixed » Needs work

This seems to have broken 10.1.x on both PHPStan and PHPCS - can’t understand how checks failed.

  • xjm committed 2193f767 on 10.1.x
    Issue #3171047 followup by xjm: Fix coding standards changes that were...
xjm’s picture

Status: Needs work » Fixed

Crosspost.

Status: Fixed » Closed (fixed)

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