Username enumeration via one time login route when logged in as another user

Created on 15 December 2022, almost 2 years ago
Updated 8 September 2023, about 1 year ago

Problem/Motivation

#2828724: Username enumeration via one time login route β†’ partially fixed this but we missed the following case. If you're logged in and visit a URL like [site_url}/user/reset/[user_id]/1/1 you'll see this message:

Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user.

Steps to reproduce

Proposed resolution

Change user interface text to not disclose the user name for the resetting user.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

πŸ“Œ Task
Status

Fixed

Version

10.1 ✨

Component
User moduleΒ  β†’

Last updated 1 day ago

Created by

πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

Live updates comments and jobs are added and updated live.
  • Security improvements

    It makes Drupal less vulnerable to abuse or misuse. Note, this is the preferred tag, though the Security tag has a large body of issues tagged to it. Do NOT publicly disclose security vulnerabilities; contact the security team instead. Anyone (whether security team or not) can apply this tag to security improvements that do not directly present a vulnerability e.g. hardening an API to add filtering to reduce a common mistake in contributed modules.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Status changed to Needs work over 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom AaronMcHale Edinburgh, Scotland

    @alexpott Yep that makes sense, I just assumed that was a change in this issue. If it has not been changed in this issue then yes let's leave it out of scope, thanks.

  • Status changed to Needs review over 1 year ago
  • πŸ‡ΈπŸ‡°Slovakia poker10

    Updating the patch according to the comment #7. Adding also simple test case and test-only patch.

  • Status changed to Needs work over 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    I think we need a follow-up to inject the time service into this class.

    Also I think we should consider making the following change to \Drupal\user\Controller\UserController::confirmCancel() which shares the same timestamp / hash / user checking logic.

    diff --git a/core/modules/user/src/Controller/UserController.php b/core/modules/user/src/Controller/UserController.php
    index d634706f3d..47ac09e84f 100644
    --- a/core/modules/user/src/Controller/UserController.php
    +++ b/core/modules/user/src/Controller/UserController.php
    @@ -406,7 +406,7 @@ public function confirmCancel(UserInterface $user, $timestamp = 0, $hashed_pass
         $account_data = $this->userData->get('user', $user->id());
         if (isset($account_data['cancel_method']) && !empty($timestamp) && !empty($hashed_pass)) {
           // Validate expiration and hashed password/login.
    -      if ($timestamp <= $current && $current - $timestamp < $timeout && $user->id() && $timestamp >= $user->getLastLoginTime() && hash_equals($hashed_pass, user_pass_rehash($user, $timestamp))) {
    +      if ($current - $timestamp < $timeout && $user->id() && $this->validatePathParameters($user, $timestamp, $hashed_pass)) {
             $edit = [
               'user_cancel_notify' => $account_data['cancel_notify'] ?? $this->config('user.settings')->get('notify.status_canceled'),
             ];
    

    I think the consistency is worth it.

    Also I think we should consider whether we should add the timeout check to \Drupal\user\Controller\UserController::validatePathParameters() - because there really is no difference between the messages:
    'You have tried to use a one-time login link that has expired. Please request a new one using the form below.'
    and
    'You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'

    And then we have less code to maintain and even more consistency.

  • Status changed to Needs review about 1 year ago
  • last update about 1 year ago
    Custom Commands Failed
  • πŸ‡ΈπŸ‡°Slovakia poker10

    Uploading an updated patch - the method confirmCancel() now uses the same validation via validatePathParameters() and the validatePathParameters() now has a new timeout parameter, so that it can be used consistently.

  • last update about 1 year ago
    29,469 pass
  • πŸ‡ΈπŸ‡°Slovakia poker10

    Removed one deprecation, so tests were failing. Let's try again.

  • Status changed to Needs work about 1 year ago
  • The Needs Review Queue Bot β†’ tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

    This does not mean that the patch needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide β†’ to find step-by-step guides for working with issues.

  • last update about 1 year ago
    29,469 pass
  • Status changed to Needs review about 1 year ago
  • last update about 1 year ago
    30,058 pass
  • πŸ‡ΈπŸ‡°Slovakia poker10

    Let's add a 11.x patch as well..

  • Status changed to RTBC about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Appear that tests are included in the patch so removing the tag.

    #13 mentions a follow up but #14 believe addresses that concern, correct me if I'm wrong.

    Looking at the patch nothing stands out so think this is good for committer review.

    • catch β†’ committed 05e95eb4 on 10.1.x
      Issue #3327294 by poker10, alexpott: Username enumeration via one time...
    • catch β†’ committed 27aba04e on 11.x
      Issue #3327294 by poker10, alexpott: Username enumeration via one time...
  • Status changed to Fixed about 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom catch

    We still need a follow-up to inject the time service, it's currently using \Drupal, so it's not using deprecated constants but it's also not injecting.

    I double checked that we already have test coverage for the 'you're trying to log in with a valid login link but you're logged in as someone else' which can easily happen during development with masquerade/test accounts/multiple browsers open etc.

    However given this fixes username unumeration happy to commit without injection to 11.x and 10.1.x, if we added injection to 10.1.x we'd be deprecating in a patch release, allowed since it's @internal but not necessary.

  • πŸ‡ΈπŸ‡°Slovakia poker10

    @catch , is the proposed follow-up already covered by this issue πŸ“Œ Replace REQUEST_TIME in classes with direct container access Fixed ? I see the core/modules/user/src/Controller/UserController.php mentioned here. Thanks!

  • πŸ‡¬πŸ‡§United Kingdom catch

    @poker10 no because that's about the constants not injection Vs the \Drupal class. As far as that meta's concerned this issue will have fixed it.

  • πŸ‡³πŸ‡ΏNew Zealand quietone

    I am not sure what Meta is referred to in #23. I looked at the other issue, πŸ“Œ Replace REQUEST_TIME in classes with direct container access Fixed and it is injecting the service in classes, including UserController. That issue does have a meta but I don't see it referring to the UserController class, except in the MR.

    So, I think that a followup is not needed here because it is being addressed in 3112298. Therefore, I am removing the tag. I trust someone will correct me if I am wrong.

  • πŸ‡¬πŸ‡§United Kingdom catch

    Oh the meta is πŸ“Œ [meta][no patch] Replace uses of REQUEST_TIME and time() with time service Active which is about removing usage of the constants. However the patch committed here doesn't inject the time service, it uses \Drupal so we could have a follow-up for that. But also it's a very minor issue so it could also just wait for someone trying to remove \Drupal calls from classes in general.

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

Production build 0.71.5 2024