Problem/Motivation

When a Views exposed role filter is applied on the user listing page
(e.g. admin/people), the administerusersbyrole
access control query tag stops filtering users correctly. Users that the
current account should not be able to see may appear in the results, or
the listing may return no results at all.

The root cause is in administerusersbyrole_query_alter(). The
LEFT JOIN that performs the access anti-join uses users_roles
as the table reference in its ON clause:

  $query->leftjoin(
    'users_roles',
    'administerusersbyrole',
    'users_roles.uid=users.uid AND users_roles.rid IN (:exclude)',
    array(':exclude' => $exclude)
  );
  

When Views applies a role filter it adds its own
INNER JOIN users_roles ON ... using users_roles
as the alias. The ON clause of the subsequent LEFT JOIN then resolves
users_roles to that already-existing alias rather than to
the new administerusersbyrole alias being declared. As a
result the anti-join operates only on the role-filtered subset of
users_roles rows instead of the full role assignment table,
and the access restriction no longer works correctly.

Steps to reproduce

  1. Install and enable administerusersbyrole,
    admin_views, and views.
  2. Create two roles, e.g. Editor and Manager.
  3. Create a user account with only the Manager role and grant
    it the access users overview permission and edit
    permission for the Editor role only (not
    Manager).
  4. Create several users: some with Editor, some with
    Manager, some with both.
  5. Log in as the Manager account and navigate to
    admin/people.
  6. Apply the Role exposed filter and select
    Editor.
  7. Observe that users with the Manager role (which the
    current account has no edit permission for) appear in the filtered
    results.

Proposed resolution

Change the ON clause of the LEFT JOIN in
administerusersbyrole_query_alter() to reference the JOIN's
own alias (administerusersbyrole) instead of the table name
(users_roles), consistent with how the
users_roles_2 join immediately above it is already written.

Before:

  $query->leftjoin(
    'users_roles',
    'administerusersbyrole',
    'users_roles.uid=users.uid AND users_roles.rid IN (:exclude)',
    array(':exclude' => $exclude)
  );
  

After:

  $query->leftjoin(
    'users_roles',
    'administerusersbyrole',
    'administerusersbyrole.uid=users.uid AND administerusersbyrole.rid IN (:exclude)',
    array(':exclude' => $exclude)
  );
  

Remaining tasks

  • Review and confirm the fix.
  • Write a regression test covering the role filter + access
    restriction combination.
  • Commit and tag a new release.

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

kaustubhb created an issue. See original summary.

kaustubhb’s picture

This patch fixes the issue

kaustubhb’s picture

This Patch has security fix

kaustubhb’s picture

Adding a patch which is compatible with patch for below issue
https://www.drupal.org/project/administerusersbyrole/issues/3311129

kaustubhb’s picture

StatusFileSize
new858 bytes
kaustubhb’s picture