Use email verification when changing user email addresses

Created on 22 September 2006, over 18 years ago
Updated 8 April 2024, 10 months ago

Problem/Motivation

Currently, when a new user registers for a Drupal account the details are sent to the user's supplied email address. This provides a basic mechanism that confirms the user is at that email address. However, once registered, users are permitted to change their email address without further confirming that the user is in fact at that email address.

Possible implications

  • A user can change email address to be that of an unsuspecting third party as no confirmation of change is required. Using a second Drupal account (with it's email address also faked using the same method) the first user is then able to send anonymous malicious messages to the unsuspecting third party
  • A slow method for sending spam but exploitable none the less

Proposed resolution

Add a mechanism (similar to reset password) that:

  1. Sends an E-mail to the new address requiring the verification of the new address (similar to register confirmation).
  2. Sends a notification E-mail to the old address.
  3. Allow the site builder to customise both messages at admin/config/people/accounts
  4. Provides an update path to set the default behaviour and messages content.
  5. Write tests.

This new mechanism is bypassed if the e-mail address is changed by an administrator.

Remaining tasks

  1. #279.2:
  2. - Not easy to test as involves email send failure - code seems OK
  3. - Addressed around #356, with new test included
  4. Security review.
  5. See #360

    1. See #360
    2. See #360
    3. See #360
    4. See #360
  6. See #360
    1. - In #312 noted admin users are generally able to do a lot of things without checks, including remove their own rights, so already trustworthy to set a new email correctly without needing to verify it
  7. #334 Create a followup for JSONAPI
  8. Don't re-use user_mail_notify or mutate the email on a cloned version of the user in case someone calls ::save() on it
  9. Add flood control to the change email controller

User interface changes

New UI additions to admin/config/people/accounts:

New confirmation message (warning) when user changes e-mail address:

Default text of the generated e-mail (some elements will vary):

alice,

A request to change your email address has been made at Drupal Usability. You
need to verify the change by clicking on the link below or copying and
pasting it in your browser:

http://drupalux.lndo.site/user/mail-change/2/alice%40example.org/1542687...

This is a one-time URL, so it can be used only once. It expires after one
day. If not used, your email address at Drupal Usability will not change.

After using the one-time link, the user is redirected to the site's home page, with the message (info)

Your email address has been changed to alice@example.org.

API changes

New controller used for mail changing: \Drupal\user\Controller\MailChangeController

Data model changes

New schema for configs user.settings and user.mail.

Release notes snippet

When users wish to change their email, they must now verify the email belongs to them using a link sent to that address. This behavior is enabled by default on new installations but disabled by default on existing installations. Review the change record โ†’ for more information.

โœจ Feature request
Status

Needs work

Version

11.0 ๐Ÿ”ฅ

Component
User moduleย  โ†’

Last updated about 3 hours ago

Created by

๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom AjK

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

    It is used for security vulnerabilities which do not need a security advisory. For example, security issues in projects which do not have security advisory coverage, or forward-porting a change already disclosed in a security advisory. See Drupalโ€™s security advisory policy for details. Be careful publicly disclosing security vulnerabilities! Use the โ€œReport a security vulnerabilityโ€ link in the project pageโ€™s sidebar. See how to report a security issue for details.

  • 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

Merge Requests

Comments & Activities

Not all content is available!

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

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany DiDebru

    Patch doesn't apply for 9.5.2

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany DiDebru

    Patch doesn't apply for 9.5.2

  • ๐Ÿ‡จ๐Ÿ‡ฆCanada No Sssweat

    Patch doesn't apply for 9.5.2

    Why bother? It has been 16 years...

    Clearly this tells me that this just a "nice to have" feature that most people are living happily without.

    Also, it seems there are a lot of hoops, walls and gates to jump through to get this into core.

    This should've been moved into contrib or scrapped all together a long time ago.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom AaronMcHale Edinburgh, Scotland

    Re-rolls should be done for the latest Core branch, so 10.1.x, not 9.5.x.

    Just because an issue has been around for a long time, and still has some work to do, doesn't make it any less valuable or worthy of inclusion in Core. If this functionality is needed for a site there are already contrib modules that will do this.

  • Status changed to Needs review almost 2 years ago
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia karishmaamin

    Re-rolled patch at #395 against 10.1.x. Please review

  • Status changed to Needs work almost 2 years ago
  • ๐Ÿ‡ญ๐Ÿ‡บHungary mxr576 Hungary

    Updated the version information in the related CR and also triggered a new build on #409 because it might have failed for transient errors before.

  • ๐Ÿ‡ญ๐Ÿ‡บHungary mxr576 Hungary

    Unfortunately, it also seems to me that the latest patch still solves this issue on the form level only and does not cover other presentation layers, like APIs. I searched for "JSONAPI" in this thread and I have only found that @larowlan was asked about that in #334 only... even though it is a fundamental building block of Drupal core now and there was an API first initiative.

    Added #344 to remaining tasks to have a clear answer for that.

  • ๐Ÿ‡ญ๐Ÿ‡บHungary mxr576 Hungary
  • ๐Ÿ‡ญ๐Ÿ‡บHungary mxr576 Hungary

    Why bother? It has been 16 years...

    Clearly this tells me that this just a "nice to have" feature that most people are living happily without.

    Let me gently disagree with this statement in #407. This is very much a requirement by enterprise companies and the fact that this is not OOTB in Drupal makes Drupal less appealing to them. Selling this as custom development does not sound good to them.

    Being that said, we have also developed our custom solution once or twice, it is not perfect either, therefore it does not worth sharing either. Plus the customer owns the code.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany luenemann Sรผdbaden, Germany
    • fix #334 reference
    • convert comment references to links with dreditors help
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States franksj

    There is a new level of indent in `user.schema.yml` so I had to adjust the spacing for the `user.mail` changes to make this apply to 9.5.4.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia sarvjeetsingh

    Updated patch for 9.5 support

  • last update over 1 year ago
    Patch Failed to Apply
  • last update over 1 year ago
    Patch Failed to Apply
  • Status changed to Needs review over 1 year ago
  • last update over 1 year ago
    Patch Failed to Apply
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany J-Lee ๐Ÿ‡ฉ๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • Status changed to Needs work over 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.

  • Status changed to Needs review over 1 year ago
  • last update over 1 year ago
    Custom Commands Failed
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia mrinalini9 New Delhi

    Rerolled patch #417 for 11.x branch, please review it.

    Thanks!

  • last update over 1 year ago
    Custom Commands Failed
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia karishmaamin

    Fixed custom command failure #421. Please review

  • last update over 1 year ago
    30,022 pass, 6 fail
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia vsujeetkumar Delhi

    Fixed CCF issues, Please have a look.

  • Status changed to Needs work over 1 year ago
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia vsujeetkumar Delhi

    Fixed fail test cases, Please have a look.

  • last update over 1 year ago
    30,057 pass, 6 fail
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    larowlan โ†’ changed the visibility of the branch 85494-use-email-verification-9.3.x to hidden.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    larowlan โ†’ changed the visibility of the branch 85494-use-email-verification-9.4.x to hidden.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    larowlan โ†’ changed the visibility of the branch force-rebase to hidden.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    Updating remaining tasks, hiding patches

    Next steps are JSON:API and a reroll.

    All other UX followups can be improved incrementally per #360

  • Merge request !5773Covert to 11.x โ†’ (Open) created by quietone
  • ๐Ÿ‡ณ๐Ÿ‡ฟNew Zealand quietone

    Locally, I apply the diff to 11.x and fixed the patch rejections from 5 files,

    ./core/modules/user/user.post_update.php.rej
    ./core/modules/user/src/AccountForm.php.rej
    ./core/modules/user/src/AccountSettingsForm.php.rej
    ./core/modules/user/config/schema/user.schema.yml.rej
    ./core/modules/user/user.module.rej

    They were all straightforward except for AccountSettings form. That needed extra work due to ๐Ÿ“Œ Introduce a new #config_target Form API property to make it super simple to use validation constraints on simple config forms, and adopt it in several core config forms Fixed . The it failed spell check and I changed usages of E-mail and Please. I also learned that the AccountSettings form does not have a test and I did not look for one.

    To do because of the changes I made to rebase.

    • Is there an issue for adding a test of AccountSettings Form? if not, make one.
    • Review all comments
    • Review all user facing text to make sure it aligns with the Usability review.
  • ๐Ÿ‡ณ๐Ÿ‡ฟNew Zealand quietone

    There is a test of the Account settings form and it is failing.

  • First commit to issue fork.
  • Pipeline finished with Failed
    about 1 year ago
    Total: 641s
    #62690
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands Lendude Amsterdam

    Account settings form has a test, and that was failing due to the changes here, so updated that test with the new settings. Change to Account settings form for two fields that needed to use #config_target

    Fixed the autowire test and added some type hints and constructor property promotion while I was at it

  • Pipeline finished with Success
    about 1 year ago
    Total: 509s
    #62693
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    larowlan โ†’ changed the visibility of the branch 85494-use-email-verification to hidden.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    Pushed some minor cleanups.

    Left a review from a security POV

    Added new tasks to the issue summary as follows:

    1. I don't think we should be cloning the user and setting the email on it, it takes one contrib hook to call $user->save() and the email change is permanent. This means not reusing user_mail_notify for sending the verification email, and a custom case in user_mail for this case. We should keep the account as is and pass an additional param for the new email.
    2. The controller needs flood control/protection to prevent brute force. This is the same as \Drupal\user\Controller\UserController::resetPassLogin
  • ๐Ÿ‡ณ๐Ÿ‡ฟNew Zealand quietone

    Made what I hope are improvements to the comments and some cleanup. Then did the low handing fruit from @larowlan review.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia darvanen Sydney, Australia

    I've made an initial attempt to add flood control. It passed a local test of one test class but then my rig broke and I need to stop for now so pushed as-is.

  • Pipeline finished with Failed
    about 1 year ago
    Total: 638s
    #70819
  • Pipeline finished with Failed
    about 1 year ago
    Total: 188s
    #73897
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States dww

    Rebased to 11.x, removed a few stray "revert" commits that had ended up in this branch.

    Pushed a commit that fixes a new bug in MailChangeController. UserMailChangeTest was failing (in GitLab CI and locally) because it was triggering this fatal error:

    Error: Call to a member function get() on null in Drupal\user\Controller\MailChangeController->page() (line 49 of core/modules/user/src/Controller/MailChangeController.php).
    

    That gets the test passing locally. Let's see what GitLab CI thinks.

    Leaving NW since there are still a lot of un-addressed MR threads I haven't gotten to, yet. Only trying to get back to green tests for now.

  • Pipeline finished with Success
    about 1 year ago
    Total: 648s
    #73901
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States dww

    The MR branch had conflicts when rebasing to 11.x due to ๐Ÿ› Harden user_pass_rehash() against attack Fixed . Since this is a security hardening issue, and these details are so important, I'm attaching a file showing the rebase conflict, and how I decided to merge the two versions. Would be wise for someone else to review this and confirm I've done it right, such that both this issue and 3277003 are happy.

  • Pipeline finished with Failed
    about 1 year ago
    Total: 573s
    #77808
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia darvanen Sydney, Australia

    #440: I've checked the change, and searched for any similar areas in the full diff, looks good to me.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom catch

    Double checked #440 as well and logic looks the same to me too.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    Copying comms from slack about the fail in ##44

    I think this might be a manifestation of the remaining point in my review regarding overloading of user_mail_notify
    because the hash is being generated with the new email (because user_pass_rehash considers email now)
    see line 145 of MailChangeController, we don't pass an email there, so it now uses $account->getEmail and because account is a cloned version of the user with the new email (which I said was dangerous) this is happening
    pretty sure that validates my reservations about using user_mail_notify with a cloned version of the account
    the risk of the temp email getting into places it shouldn't was a genuine fear it seems
    but in the controller it uses the old email so the hash doesn't match

  • ๐Ÿ‡ณ๐Ÿ‡ฟNew Zealand quietone

    I checked the old MR and ported the three unresolved comments/question to the current MR. My apologies if that is repeating answered questions. I figured it was better to do that instead of me reading all the comments to get up to speed.

  • Pipeline finished with Failed
    12 months ago
    #85756
  • Pipeline finished with Success
    12 months ago
    #85766
  • Status changed to Needs review 12 months ago
  • ๐Ÿ‡ณ๐Ÿ‡ฟNew Zealand quietone

    I did a bit of work on this. This is new stuff for me so I just did what made sense to me today. There are still unresolved comments to address but it would be good to review the changes I made.

  • Pipeline finished with Success
    12 months ago
    Total: 562s
    #86479
  • InaW โ†’ changed the visibility of the branch 85494-use-email-verification to active.

  • I rerolled the patch from #409 ๐Ÿ› Use email verification when changing user email addresses Needs work for 10.2.3

  • Status changed to Needs work 12 months ago
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    Left a review, there are also some aspects of #279 that are yet to be addressed

  • Pipeline finished with Failed
    12 months ago
    Total: 484s
    #93817
  • Pipeline finished with Success
    12 months ago
    Total: 694s
    #93846
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    We discussed this again in the monthly bugsmash meeting and resolved to move this to a feature request because:

    a) it is adding new features
    b) there is a contrib module for this

    Involved in the discussion were catch, griffynh, Amber Hines Matz, quietone, longwave and myself.

  • Pipeline finished with Failed
    10 months ago
    Total: 360s
    #129849
  • Pipeline finished with Success
    10 months ago
    Total: 2131s
    #138694
  • ๐Ÿ‡จ๐Ÿ‡ณChina lawxen

    Reroll #417 for drupal 9.5.11

  • ๐Ÿ‡จ๐Ÿ‡ณChina lawxen
  • Pipeline finished with Success
    7 months ago
    Total: 240s
    #204559
  • Pipeline finished with Success
    7 months ago
    Total: 211s
    #204560
  • Pipeline finished with Success
    7 months ago
    Total: 249s
    #205426
  • Pipeline finished with Success
    7 months ago
    Total: 278s
    #205478
  • Pipeline finished with Success
    7 months ago
    Total: 218s
    #206766
  • Pipeline finished with Success
    6 months ago
    #244665
  • Pipeline finished with Success
    6 months ago
    Total: 410s
    #244684
  • Pipeline finished with Skipped
    6 months ago
    #246755
  • Pipeline finished with Canceled
    12 days ago
    Total: 333s
    #393171
  • Pipeline finished with Success
    12 days ago
    Total: 984s
    #393172
  • Pipeline finished with Success
    11 days ago
    Total: 848s
    #393207
  • Pipeline finished with Skipped
    9 days ago
    #395026
Production build 0.71.5 2024