Drupal is a registered trademark of Dries Buytaert

view_usernames

218 sites Security covered
View on drupal.org

The module is part of the User Privacy Core recipe.

This module addresses Drupal core’s username information disclosure problem, which could be considered a personal data breach. For more information, see the issue on Drupal.org:
[policy] Consider username enumeration a privacy breach.

Additionally, the way usernames are currently handled in Drupal core, especially when the JSON:API core module is enabled, can leak information about the existing user base of a site. In the enterprise world, such information could provide a competitive advantage to competitors in the same market. See the Steps to reproduce section of the issue
Make username access configurable and not implicitly allowed
on Drupal.org.

What this module does

  • Introduces a new site-wide permission called “View usernames”.
  • By default, a user’s username is only visible to another user if one of the following is true:
    • The former user is Anonymous, also known as the non-logged-in user profile in Drupal.
    • The two users are the same (in other words, you can always view your username).
    • The latter user has either the “Administer users” permission or the “View usernames” permission.
  • Introduces a new API for extending the above-described system with new “deciders” that can grant access to view usernames based on custom business logic.

Under the hood

This module ensures that neither $user->getDisplayName() nor '#theme' => 'username' exposes a user’s username
to another user unless at least one of the view username deciders grants access to the acting user. This is implemented in a way that guarantees usernames are not exposed, even if proper access checks are not performed (see below).

Proper access checking for usernames:

/** @var \Drupal\user\UserInterface $user */
$user = User::load(1);
$build[] = [
  '#theme' => 'username',
  '#account' => $user,
  '#cache' => [
    'tags' => $user->getCacheTags(),
  ],
  // Check if the _current_ user can view this user's username.
  '#access' => $user->access('view label', NULL, TRUE),
];

How to extend

  1. Create a new class that implements the \Drupal\view_usernames\Contracts\ViewUsernameAccessDeciderInterface
    interface.
  2. Register it as a service and tag the service with the view_username_access_decider tag.
  3. (Optional) Add a custom priority to the service to move it higher or lower in the execution order.

See the view_usernames.view_username_access_decider.default service definition as an example.

You can also refer to existing implementations of the \Drupal\view_usernames\Contracts\ViewUsernameAccessDeciderInterface
interface as examples for building a custom decider.

Rules for building a decider

  • A decider MUST NOT depend on contextual dependencies (e.g., current route match, current request, current user, etc.).
    It MUST be able to make a decision based on the $acting_user and $other_user parameters.
    • The current_user service dependency can be considered an exception to this rule because it may be necessary for
      optimizing calculated cacheability information, but only for solving this particular problem. In Drupal core and
      contrib modules, 99% of the time, a dependency on the current user is added when the acting user might not be the same.
      See the related Drupal core issue: Access result caching per user (.permissions) does not check for correct user.

Known limitations

Activity

Total releases
2
First release
Jul 2025
Latest release
2 months ago
Release cadence
148 days
Stability
100% stable

Releases

Version Type Release date
1.2.0 Stable Dec 14, 2025
1.1.0 Stable Jul 19, 2025