filter.routing.yml uses permissions to perform access control on routes instead of _entity_access. This bypasses filter entities' access controller and hook_entity_access() and variants, and is therefore a potential security flaw.

This issue CANNOT be committed until #2095693: FilterFormatAccessController always grants access for any operation on the fallback format is, or we will have introduced an actual security bug.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Xano’s picture

Status: Active » Needs review
FileSize
4.38 KB

The patch replaces _permission with _entity_access and _entity_create_access for routes that want to perform entity operations. It cleans up the access controller and provides proper access control for the disable operation. Consequently it also removes the access check that was used for the route that disables formats.

Status: Needs review » Needs work

The last submitted patch, drupal_2101119_1.patch, failed testing.

Xano’s picture

I forgot to mention that because of the security implications, I made sure this patch depends on #2095693: FilterFormatAccessController always grants access for any operation on the fallback format.

Xano’s picture

Status: Needs work » Needs review

#1: drupal_2101119_1.patch queued for re-testing.

Xano’s picture

#1: drupal_2101119_1.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, drupal_2101119_1.patch, failed testing.

Xano’s picture

Assigned: Xano » Unassigned
Status: Needs work » Needs review
FileSize
4.5 KB

Re-roll.

tim.plunkett’s picture

FileSize
4.39 KB
1.81 KB
+++ b/core/modules/filter/lib/Drupal/filter/FilterFormatAccessController.php
@@ -20,25 +20,26 @@ class FilterFormatAccessController extends EntityAccessController {
+      return $entity->isFallbackFormat() || $account->hasPermission($entity->getPermissionName());

It turns out this is redundant. FilterFormat::getPermissionName() checks isFallbackFormat() already. Restoring the previous !empty() check from before.

Also quoting the access bits like we do elsewhere.

Xano’s picture

It turns out this is redundant. FilterFormat::getPermissionName() checks isFallbackFormat() already. Restoring the previous !empty() check from before.

I know it is redundant, but it makes much more sense when reading the code. getPermission() should IMHO also return a permission string at all times, even if it is for a fallback format.

Status: Needs review » Needs work

The last submitted patch, filter-2101119-8.patch, failed testing.

Xano’s picture

8: filter-2101119-8.patch queued for re-testing.

The last submitted patch, 8: filter-2101119-8.patch, failed testing.

sun’s picture

Issue summary: View changes
+++ b/core/modules/filter/lib/Drupal/filter/FilterFormatAccessController.php
@@ -20,25 +20,27 @@ class FilterFormatAccessController extends EntityAccessController {
+    // All users are allowed to view the fallback filter.
+    if ($operation == 'view') {
+      $permission = $entity->getPermissionName();
+      return !empty($permission) && $account->hasPermission($permission);
     }

This looks a bit scary to me...

Is a text format really "viewed" when being presented in a text field widget? (No, it is not.)

Or isn't a text format much rather "viewed" when being listed on the administrative overview page that lists all available text formats?

→ I think we need to make a differentiation between "use" and "view".

Given recent entity access/operation API improvements, it might be much more simple now to introduce a new operation/access model of "use"?

Xano’s picture

Status: Needs work » Needs review
FileSize
4.68 KB

Re-roll, and I introduced the use operation per sun's request.

Status: Needs review » Needs work

The last submitted patch, 14: drupal_2101119_14.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
4.84 KB
696 bytes

Status: Needs review » Needs work

The last submitted patch, 16: drupal_2101119_16.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
8.08 KB
2.72 KB

Status: Needs review » Needs work

The last submitted patch, 18: drupal_2101119_18.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
9.04 KB
885 bytes
Xano’s picture

20: drupal_2101119_20.patch queued for re-testing.

sun’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, @Xano! — This looks good to me.

Somehow I assumed/hoped that a new access operation would have to be registered somewhere (so that available operations can be discovered and introspected by other services and developers), but based on this patch, that doesn't appear to be the case yet.

I also wondered whether the "administer filters" permission still kicks in somewhere, but I assume the "admin_permission" on the FilterFormat entity class annotation is automagically used and validated by the config entity system.

tim.plunkett’s picture

I also wondered whether the "administer filters" permission still kicks in somewhere, but I assume the "admin_permission" on the FilterFormat entity class annotation is automagically used and validated by the config entity system.

Yep, the parent::checkAccess call uses the admin_permission annotation, see EntityAccessController::checkAccess

+1 for RTBC

catch’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/filter/lib/Drupal/filter/FilterFormatAccessController.php
@@ -19,26 +19,28 @@ class FilterFormatAccessController extends EntityAccessController {
+    if (in_array($operation, array('disable', 'view', 'update'))) {

Patch removes 'view' from almost everywhere, but not here. I realise this is just punting it to the parent, but is 'view' even used any more? If it's not, I'm not really convinced about the view/use change - leaves view hanging with no purpose at all, and this feels like an issue for most configuration entities.

tim.plunkett’s picture

Status: Needs review » Needs work

This also removes the only place that _filter_disable_format_access is used, so the access_check.filter_disable service and corresponding Drupal\filter\Access\FormatDisableCheck class can be removed.

Xano’s picture

Status: Needs work » Needs review
FileSize
9.03 KB
1.38 KB

Patch removes 'view' from almost everywhere, but not here. I realise this is just punting it to the parent, but is 'view' even used any more? If it's not, I'm not really convinced about the view/use change - leaves view hanging with no purpose at all, and this feels like an issue for most configuration entities.

You're right. I removed view from the access controller.

This also removes the only place that _filter_disable_format_access is used, so the access_check.filter_disable service and corresponding Drupal\filter\Access\FormatDisableCheck class can be removed.

The patch already did that?

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community

I must have accidentally clicked on another patch, I was just staring at FormatDisableCheck for another reason and thought I'd make a note here.

Thanks @Xano!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 26: drupal_2101119_26.patch, failed testing.

Xano’s picture

26: drupal_2101119_26.patch queued for re-testing.

Désiré’s picture

Status: Needs work » Needs review
Désiré’s picture

26: drupal_2101119_26.patch queued for re-testing.

Xano’s picture

Status: Needs review » Reviewed & tested by the community
Désiré’s picture

26: drupal_2101119_26.patch queued for re-testing.

Xano’s picture

RTBC patches no longer have to be re-tested manually: https://qa.drupal.org/node/228

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 26: drupal_2101119_26.patch, failed testing.

Xano’s picture

26: drupal_2101119_26.patch queued for re-testing.

Xano’s picture

Status: Needs work » Reviewed & tested by the community

Random test failure? Back to RTBC.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 26: drupal_2101119_26.patch, failed testing.

Xano’s picture

26: drupal_2101119_26.patch queued for re-testing.

Xano’s picture

Status: Needs work » Reviewed & tested by the community

RTBC'ing per #27 and #37.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 26: drupal_2101119_26.patch, failed testing.

Xano’s picture

Status: Needs work » Reviewed & tested by the community

The tests fail because HEAD is broken.

tstoeckler’s picture

26: drupal_2101119_26.patch queued for re-testing.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.x, thanks!

  • Commit 973948e on 8.x by catch:
    Issue #2101119 by Xano, tim.plunkett: Convert Filter routes to use...

Status: Fixed » Closed (fixed)

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