Problem/Motivation

I have reported this bug to the security team yesterday and they made clear they don't consider it a security issue due to the username enumeration policy of Drupal. I believe that's a matter of some debate. I will post the issue here (as suggested), because of the reason the finding will not be forgotten when the view on this topic changes in the future.

I found that there is a noticeable difference (~ 1.5 second) between requesting a password reset for an existing account and a non-existent one. This difference makes it possible to find out whether an account exists or not (timing attack).

The noticeable difference in response timing is due to Drupal sending the mail if the account exists (which takes approximately a second) and just returning the response when an account does not exist (approximately 50 ms).

Example of response times for three consecutive requests:

Request Existing account Non-existent account
#1 1,574 ms 57 ms
#2 1,426 ms 40 ms
#3 1,823 ms 54 ms

Proposed resolution

To prevent timing attacks, the following solutions could be considered:

  • Change the execution order so that when a new password is requested a response is immediately returned to the user and the mail is sent afterwards.
  • Another way to prevent a timing attack is to provide the password reset function a fake user so the whole process is performed on a non existing user. This will take the same amount of time and will therefore prevent a timing attack.
  • Alternatively, have the application respond with the same general message for the password reset request, whether the entered mail address is valid or not. Send a mail to the entered e-mail address in both cases. In the case the user is unknown in the database simply let the message in the mail contain something like "A password reset has been requested for your account but according to our information there is no account registered with your address.".

Steps to reproduce

  • Install the Drupal product with the versions listed above and configure an external mail provider.
  • Request a new password for an existing user and repeat this request in a proxy tool like BurpSuite. This tool provides the response times for repeated requests.
  • Perform the same request for a non-existent username and notice the difference.

Steps to reproduce

The following modules/versions have been tested:

  • Drupal (9.4.8) and the SMTP Authentication Support (8.x-1.1) module was used. However, I saw the same issue arise when using Swiftmailer (so probably, the bug is located at Drupal Core).

Comments

Maikkeyy created an issue. See original summary.

avpaderno’s picture

cilefen’s picture

Issue tags: -Security

I am updating the tags according to their specific definitions. You can hover over the tags in the sidebar to see their metadata. In this case "Security improvements" is preferred over "Security".

cilefen’s picture

I am removing the a duplicate issue reference. Sorry about the noise.

cilefen’s picture

Component: documentation » user system

Again, sorry about the noise. This was in the documentation component, which is maintained by a specific group of contributors. As this is not a documentation but I am moving it to the user module, the most likely spot.

It would be helpful to know if enqueuing the emails, with, for example, https://www.drupal.org/project/queue_mail, eliminates the bug.

solideogloria’s picture

I don't think sending an email to a non-existent account would be a good idea, as it would allow spam to be sent to arbitrary email addresses due to repeated requests for password reset for that email address.

Version: 10.0.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

catch’s picture

With #1189464: Add an 'instant' queue runner we could create a queue item during the form submission, and then run that queue at the end of the request (after the response is sent) to actually send the email.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

catch’s picture

#1189464: Add an 'instant' queue runner has an MR now so could be built upon here. So add a 'password reset request' queue, always create the queue item when the form is submitted, run the queue at the end of the request.

catch’s picture

Title: Leakage usernames (timing attack) » Leakage usernames (timing attack) from password reset form