.../rest/src/Plugin/rest/resource/EntityResource.php | 13 ++++++++++++- core/modules/rest/tests/modules/rest_test/rest_test.module | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php index b4352b7..8f399e2 100644 --- a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php +++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php @@ -232,10 +232,21 @@ public function patch(EntityInterface $original_entity, EntityInterface $entity $field = $entity->get($field_name); $original_field = $original_entity->get($field_name); + // If the user has access to view the field, we need to check update + // access regardless of the field value to avoid information disclosure. + // (Otherwise the user may try PATCHing with value after value, until they + // send the current value for the field, and then they won't get a 403 + // response anymore, which indicates that the value they sent in the PATCH + // request body matches the current value.) + if (!$original_field->access('view')) { + if (!$original_field->access('edit')) { + throw new AccessDeniedHttpException("Access denied on updating field '$field_name'."); + } + } // Check access for all received fields, but only if they are being // changed. The bundle of an entity, for example, must be provided for // denormalization to succeed, but it may not be changed. - if (!$original_field->equals($field) && !$original_field->access('edit')) { + elseif (!$original_field->equals($field) && !$original_field->access('edit')) { throw new AccessDeniedHttpException("Access denied on updating field '$field_name'."); } $original_entity->set($field_name, $field->getValue()); diff --git a/core/modules/rest/tests/modules/rest_test/rest_test.module b/core/modules/rest/tests/modules/rest_test/rest_test.module index 7df2863..469b4c7 100644 --- a/core/modules/rest/tests/modules/rest_test/rest_test.module +++ b/core/modules/rest/tests/modules/rest_test/rest_test.module @@ -15,6 +15,7 @@ * * @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::setUp() * @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::testPost() + * @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::testPatch() */ function rest_test_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) { if ($field_definition->getName() === 'field_rest_test') {