Problem/Motivation
Currently two users can register with same email address: one use as username and another one use as email. When the user with the username that is an email address (that does not match their email address) navigates to user/password
to reset password, they cannot receive the reset email because the user password reset form allows entering either a username or email, an the notification goes to the account that has that as the email.
Also, @catch asked for this in #111317-83: Allow users to login using either their username OR their e-mail address
Steps to reproduce:
- Create first user with username a@example.com and email b@example.com.
- Create second user with mail a@example.com and an arbitrary username.
- Go to
user/password
to reset password, enter a@example.com. - Password email will be sent to a@example.com; the first user (with username a@example.com and the email b) will not get a password email. (The only way for them to get the password reset would be to request for the email b@example.com.)
Proposed resolution
When new users register, check the username and email fields against already registered users to make sure the username is not already registered as an email and vice versa.
To deal with already registered users who have conflicts, users who have matching emails and usernames are allowed to select which user to email the password reset link to when resetting their password.
Remaining tasks
- (done) document/update steps to test/reproduce (how to: http://drupal.org/node/1468198) (see #44, #51, )
- get screenshot of error when following the steps to reproduce, at step 2.
- get screenshot of the other way around: 1) create a user with arbitrary username and email a@example.com. 2) create another user with username a@example.com and email b@example.com
User interface changes
Password reset form UI change: If it detects a conflict with username/email, it allows the user to pick which account they meant. Screenshot:
After shot 2 in #117 shows some errors.
API changes
N/A
Original report by hefox
Seems like it should be part of validation due to how email is used. Edge case, but could happen with forgetful users.
1) Make a user with username 'example@example.com' and email != that
2) Make a user with mail 'example@example.com'
3) Go to user/pass to reset password, enter 'example@example.com'.
4) Password email will be sent to example@example.com; the first user will not be able to get a password email with username.
There should be an option to disable the password strength check in the settings for user registration. Right now it can only be disabled by a custom module with a hack messing with the javascript function that checks the password.
Comment | File | Size | Author |
---|---|---|---|
#277 | interdiff_275_277.txt | 1.56 KB | Ajeet Tiwari |
#277 | 1359718-277.patch | 2.9 KB | Ajeet Tiwari |
#275 | 1359718-275.patch | 2.8 KB | Ajeet Tiwari |
#273 | 1359718-nr-bot.txt | 4.5 KB | needs-review-queue-bot |
#272 | 1359718-272.patch | 61.93 KB | Rassoni |
Issue fork drupal-1359718
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
rbayliss CreditAttribution: rbayliss commentedA test to demonstrate the issue (should fail). Do we seriously not have a test for duplicate usernames yet, or am I just missing it?
Comment #2
rbayliss CreditAttribution: rbayliss commentedA patch to crosscheck the username against the email field and vice-versa. Also includes the aforementioned tests.
Comment #3
rbayliss CreditAttribution: rbayliss commentedComment #4
Everett Zufelt CreditAttribution: Everett Zufelt commentedDidn't test, but looking over the patch it looks good.
See also #111317: Allow users to login using either their username OR their e-mail address.
Comment #5
Everett Zufelt CreditAttribution: Everett Zufelt commentedSwitching to User.module. To clarify, this patch places a constraint on the User.module, not on the user system. Important distinction should the User.module become plugable in the future.
Comment #6
marvil07 CreditAttribution: marvil07 commentedPatch looks right.
Only a minor formatting thing:
Is that extra line needed?
-27 days to next Drupal core point release.
Comment #7
kathyh CreditAttribution: kathyh commentedApplied changes per #6
Comment #9
kathyh CreditAttribution: kathyh commentedhmmm - reverting to original patch from #2. Please use patch #2 above.
Comment #11
kathyh CreditAttribution: kathyh commentedTrying to get it back to #2 then will change to needs work (for #6).
Comment #12
udaksh CreditAttribution: udaksh commentedComment #13
udaksh CreditAttribution: udaksh commented#2: username_email_crosscheck-1359718-2.patch queued for re-testing.
Comment #14
udaksh CreditAttribution: udaksh commentedComment #15
marvil07 CreditAttribution: marvil07 commentedThis should only need to change the formatting detail mentioned on #6 and I would say it's ready.
BTW this affects directly one core functionality, so moving to normal.
Comment #16
cosmicdreams CreditAttribution: cosmicdreams commentedI think I've squashed the single space issue that #15 is talking about.
Comment #17
cosmicdreams CreditAttribution: cosmicdreams commentedturning to needs review so test bot wakes up
Comment #18
marvil07 CreditAttribution: marvil07 commentedThanks!
Comment #19
Niklas Fiekas CreditAttribution: Niklas Fiekas commentedSorry to set this back on these minors:
The assertion message 'Supplying an exact ...' should not be wrapped in t().
Same thing here.
Comment #20
cosmicdreams CreditAttribution: cosmicdreams commentedWithout t() what would be the best way to do keyword replacement? preg_replace()?
Comment #21
marvil07 CreditAttribution: marvil07 commented@cosmicdreams: It's only about the second parameter, not the first one ;-)
Comment #22
cosmicdreams CreditAttribution: cosmicdreams commentedHere's the cleaned up patch
Comment #23
cosmicdreams CreditAttribution: cosmicdreams commentedswitch to patch review mode.
Comment #24
marvil07 CreditAttribution: marvil07 commentedThanks!
BTW Thanks to Niklas Fiekas for the review too.
Comment #25
xjmThanks @Niklas Fiekas, @marvil07, and @cosmicdreams. Few more minor points for cleanup:
Egad. I know it was already this way, but damn are these hard to read.
This test method needs a docblock. Reference: http://drupal.org/node/1354#functions
The assertion messages here (final arguments) should not be translated with t(). Reference: http://drupal.org/simpletest-tutorial-drupal7#t
Comment #26
xjmAlso, we should backport this fix.
Comment #27
Niklas Fiekas CreditAttribution: Niklas Fiekas commentedWe shouldn't touch this just for cleaning it up. I suppose you did this cleanups because I wasn't very clear about the t(...) thing.
Actually I meant this one.
And this one. Sorry.
Comment #28
mottihoresh CreditAttribution: mottihoresh commented#1: username_email_crosscheck-1359718-1.patch queued for re-testing.
Comment #29
cosmicdreams CreditAttribution: cosmicdreams commentedI'll have an opportunity to fix the patch later tonight.
Comment #30
xjmAh, I spaced out and didn't notice those lines weren't part of the fix. @Niklas Fiekas is correct; we should not have any changes in
user.test
outside of the new test method.Comment #31
cosmicdreams CreditAttribution: cosmicdreams commented@Niklas Fiekas I've read and reread you post at #27 and I'm confused. You seem to be objecting to the two changes I made in the patch and then you are telling me that I should have made those very same changes.
If I'm not adhering to a coding standard by ensuring that the line of code stays less that 80 characters wide please let me know. But I think you should reread what you post and let me know if you're seeing the same thing I am.
To be clear, The reason why the patch is effecting more lines of code that may seem necessary is because I am separting the parameters given to the assertion statement onto different lines. This was done to ensure that I didn't produce a line of code that was greater than the outer limit of characters.
Comment #32
xjm@cosmicdreams, the changes are incorrect because they are outside the lines being added by the patch. They already exist in the codebase and are not being altered functionally. (Compare with your previous patch in #16.) We don't add cleanups that are not specifically a part of the functional patch, because it causes scope creep, makes the patch harder to review, and makes it more likely to collide with other issues.
Also, the 80-character rule is only 100% required for comments. It is just strongly recommended for executable code, and one common exception is assertions. IMO the assertions should either be all on one line, or have all the parameters on separate lines similar to our multi-line array formatting. (Reference: http://drupal.org/coding-standards#array) Edit: But, again, the lines Niklas pointed out should not be changed at all in this patch.
Thanks for your work on this!
Comment #33
cosmicdreams CreditAttribution: cosmicdreams commentedthanks for the clarification. If I cleanup what is itemized in #25, can we call this done?
Comment #34
cosmicdreams CreditAttribution: cosmicdreams commentedhere's the corrected patch:
1. only cleaned up the previous modified section of the user tests
2. included the doc block
Comment #36
xjmLooks like the patch has a syntax error.
Additionally, this should be less than 80 chars and end in a period. Reference: http://drupal.org/node/1354#functions
Comment #37
Niklas Fiekas CreditAttribution: Niklas Fiekas commentedYes, the trailing S.
Comment #38
cosmicdreams CreditAttribution: cosmicdreams commentedEeesh, that's embarrasing.
1. fixed the syntax error that I should have caught before submitting
2. Discovered my IDE had it's right text boundary set to 120 characters instead of 80. Fixed the length of the comment.
Comment #39
cosmicdreams CreditAttribution: cosmicdreams commentedescalating to review mode.
Comment #41
no_commit_credit CreditAttribution: no_commit_credit commentedComment #42
xjmAbove corrects the function summary to be one line less than 80 chars ending in a period.
The failure of the test without the fix is exposed in #1. Coding standards are met, patch resolves the issue, etc. So pending testbot, I think this is RTBC. Thanks for your patience with all the rerolls!
Comment #43
catchFor existing users where this is already the case, what are we going to do?
I don't see any discussion in this issue on how to deal with that. While the upgrade path would need to happen in Drupal 7, it'd be good to have some kind of plan on how to deal with it before this gets committed to 8.x - seems like at the moment it'd force someone to change their username - maybe that's OK since it's an edge case, but worth asking.
Comment #44
xjmWell, per the code comments and user_account_form_validate(), it's only validating:
So existing users wouldn't be forced to change their usernames. However, they'd be forced to change their email addresses if someone else has the same email as a username, if I'm understanding correctly.
Reformatting the queries because they are so darn hard to read. This happens only if
$form_state['values']['name']
is set and the name does not fail validation:And this is always:
Probably a good idea to have some manual testing for what happens to existing username/email collisions before and after this patch is applied.
a@example.com
and emailb@example.com
a@example.com
and an arbitrary username.And let's please reformat the queries as above in the patch.
Comment #46
Niklas Fiekas CreditAttribution: Niklas Fiekas commentedProbably we'll have to do something like catch's suggestion. Requiring users to change the email adress is not acceptable - usernames can be changed with a lot less trouble. Also, we're targeting #111317: Allow users to login using either their username OR their e-mail address, which would require us to eliminate all of those occurences one way or another.
Comment #47
catchI'm pretty sure user_account_form_validate() is lying, and that it validates any username that gets submitted whether it's new, changed or the same.
Comment #48
xjmSo maybe this is just not backportable? Or for backport we do it on the registration form only? Edit: and be sure we are only validating changes, not every submission.
Comment #49
xjmAn aside, I've run into user form validation getting stuck on the unchanged email field in the past for existing users, and it's a real UX WTF.
Comment #50
catchEven if it's not backportable, if we apply it to Drupal 8, then any site that upgrades to Drupal 7 that has this problem is going to run into it.
Comment #51
webchickGreetings from Core Office Hours! :)
This patch needs a re-roll after #1174620: Add new HTML5 FAPI element: email. I attempted to do that. :)
I decided to test catch's very rational-sounding theory:
I created two users:
User 1: username: bananas@mailinator.com, e-mail: not-bananas@mailinator.com
User 2: username: bananas, e-mail: bananas@mailinator.com
Confirmed that both users could log in/log out fine, and that a password reset on 'bananas@mailinator.com' went to user 2, not user 1.
Applied the patch.
I was still able to log in as both users fine, so no change there.
I go to user 1's account edit page and save it. I get error: "The name bananas@mailinator.com is already taken."
I go to user 2's account edit page and save it. I get error: "The e-mail address bananas@mailinator.com is already taken."
user 2 is basically fine, because they can choose a different e-mail address (but it creates a huge panic-y WTF: "How did someone steal my e-mail address?!"). But user 1 is screwed, unless "change username" permissions are on for auth users, which they are not by default. In either case, the site maintainer's probably getting an email about it.
An upgrade path for this is tricky... we don't really want to inject legacy checks for this condition on every single login from now until forever. Ideally, it'd be something like we show the list of affected users during update.php and kick to the site maintainer to deal with by hand (I wouldn't think there's more than a handful of these types of accounts on a handful of Drupal sites).
To me that feels more appropriate for D8 than D7. But a D8 upgrade is going to include 80 bazillion other things, so any messages are likely to get lost. :\ Hrm. Will do some thinkering.
Comment #52
webchickOops. patch.
Comment #53
webchickAnother thought. Don't change the validation at all. Instead change the password reset form so that if it detects a conflict with username/email, it allows the user to pick which account they meant (or has them type in the exact username or whatever). That would be safe to backport.
Comment #54
xjmThis. I like this!
Comment #55
xjmNew novice task: let's try to make a new patch like webchick describes in #53. We can even reuse the same test from #52.
Comment #56
adharris CreditAttribution: adharris commentedI think I've got #53 working. If the entered email address is matched to one user's name and another's email address, the form is redisplayed asking the user to pick between the two accounts. I made sure to not display another user's email address to the user attempting a password reset, but both usernames are still displayed which might be a privacy issue. Anyone want to weigh in on what the appropriate labels to display would be?
Comment #57
xjmGreat patch! I love the thorough test coverage. Thanks @adharris.
Regarding the privacy question, I think it is not a problem because we are already implicitly confirming an account exists when we allow the password reset email to be sent. Also, webchick has pointed out before that usernames are not secret. However, tagging for security review just to get confirmation that this workflow is OK.
I did a code review and have a couple questions plus a number of stylistic cleanups:
I'm concerned that this looks like an API change, even though these arguments are already implicitly available to the form builder. Core never calls
user_pass()
directly, but theoretically some code somewhere could do so anddrupal_render()
it, right? (Or am I totally mistaken?) And if so, could we get around it by factoring the logic into a helper for backport?I'd suggest adding a couple inline comments explaining the multistep form. (A couple other comments in this function might be good, too.)
These labels should be sentence-cased. Reference: http://drupal.org/node/604342#capitalization
Typo: The word "to" is repeated twice. It would also be good to make the text a little shorter, though I'm not sure how. It might be good to take some screenshots of the workflow and ask for a UX review. (Shrink browser windows to 600px & crop screenshots to the relevant portions.)
We might consider separate submit handlers for these rather than the old "clicked button" stuff. I think we could retain the previous submit handler as a wrapper for backport, and remove it in D8?
"one-time" should be hyphenated.
Minor nitpick: The first word should be a third-person verb ("Tests", "Attempts"). Reference: http://drupal.org/node/1354#functions
Also, "resetting" should not be capitalized.
I was a little confused by this comment... perhaps "For backwards compatibility" rather than "To maintain upgradability"?
Typo here (semicolon).
Missing period at the end of the assertion message here.
Here I'd specify "the user with the matching username".
I'd reword this slightly as:
It would be a fairly simple novice task to reroll this patch and clean up the simpler points above. Another good task would be to do manual testing similar to what webchick did in #51 and take screenshots of each stage in the workflow to facilitate some UX review and help us bikeshed the UI text. :)
Comment #58
xjmComment #59
Kristen PolI manually tested and it worked as expected but I will not mark RTBC because my email server was not configured correctly so the emails ended up not being sent. I did confirm that the appropriate email addresses were shown in the error log though so I'm 99.999% confident that it works as expected.
Comment #60
cossovich CreditAttribution: cossovich commentedI'm going to update the patch from #56 (taking into account the feedback from @xjm) and add some screenshots... everybody stand back!
(but please call an ambulance if you see core holding me down and kicking me in the guts).
Comment #61
webchickLOL. :) Godspeed, cossovich!
Comment #62
cossovich CreditAttribution: cossovich commentedRe-rolled patch from #56, here's a summary of the changes I made based on feedback from #57:
Tested the re-roll with the following setup (following #51).
User 1: username: thisuser@mailinator.com, email: notthisuser@mailinator.com
User 2: username: user3 email: thisuser@mailinator.com
Screenshots attached showing the request new password UI when a conflict occurs.
Comment #63
adharris CreditAttribution: adharris commentedThe API change concern is the change in the function signature. Anywhere in contrib that calls user_pass() would do so without passing the form and form_state arguments. I'm not sure on the right fix here; to the best of my knowledge a multi-stage form needs to have form_state available. So if someone calls user_pass() and then drupal_render()s it, would they lose the multi-stage functionality?
Perhaps the work around is to just func_get_args() and set $form_state = form_state_defaults()? Not sure what the effect of that would be. We could also just change the signature to
function user_pass($form = NULL, &$form_state = NULL)
though once again I'm not sure what the effects of that would be.For #5, @xjm was saying we should attach a separate submit handler to the Cancel button. Then the go back functionality is in it's own handler and the button check here:
would not be necessary.
Comment #64
xjmNice thorough job with the cleanup and the manual testing. Thanks @cossovich!
Thanks also for the screenshots with the patch applied. I've cropped the second screenshot here to show the form for reviewers. (In general, when creating screenshots, it's a good idea to use a narrow browser window and crop the image to only the relevant portion. That way they can be neatly embedded in issue comments and handbook pages using an
<img>
tag.)From this screenshot, I notice that the formatting for separating the username and email address is a little weird. At the least, there should be a space before the slash, though maybe we can improve it in other ways.
That's the correct choice. We should adhere to the standard in the lines added by our patch, but also keep within the scope of the issue. (The existing and unchanged summaries are being cleaned up in #1326666: Clean up API docs for user module.)
Attached interdiff shows the changes from #56 for easier code review.
Comment #65
no2e CreditAttribution: no2e commentedI feel like step 2 (from #62) could be a privacy problem.
If you register an account with a certain mail adress as nickname and use the form to request your password:
1. You get to know that there is a user with that certain email adress registered at this site.
"Oh look, my fiancée has an account at adult-dating.example.com"
2. You get to know the UID of that user. Now you can visit her user page, see her nickname and identify that user.
"Oh look, my fiancée is actually the user named alice23 – let me check her profile …"
Comment #66
xjmRegarding #65, #1 is not a regression--we already confirm that implicitly when we let them use the password reset form. Usernames and UIDs are not considered secret. #2 is more of a concern because, as you say, we are displaying the relationship between the account name and email, which is a regression. Though, the chances that a person could exploit this are small considering they'd have to stumble on this weird edge case to begin with. But still needs some review, I think.
That said, though, maybe we should add back something to enforce that you can't create new accounts with a username or email address that is someone else's username or email. We just leave existing accounts alone with some workaround like the above.
Comment #67
no2e CreditAttribution: no2e commented@ #66: You are right, xjm: the first one is a separate issue. I created a feature request for that:
#1521996: Password reset form reveals whether an email or username is in use
Comment #68
adharris CreditAttribution: adharris commented@no2e's second point demonstrates well what I was feeling yet could not figure out how to articulate. Furthermore, it seems extremely exploitable to me because these type of account collisions can be intentionally created:
It seems to me (3) can be fixed with two easy changes:
This of course wouldn't fix @no2e's concerns in #1521996: Password reset form reveals whether an email or username is in use, but it seems to at least not be a regression: the only information that the user gets out of the reset password process is whether or not an email is associated with an account.
Comment #69
xjmThat does seem like a much better approach. Let's update the patch with those changes, plus add some validation to disallow creating new accounts (leave existing alone) where the username duplicates an existing email address or vice versa.
Comment #70
star-szrComment #71
star-szrHere's a reroll along with the text changes. We still need to use a different id for the form elements than uid, I couldn't quite figure that one out.
Comment #72
xjmSending to the bot. Thanks @Cottser!
Comment #73
ZenDoodles CreditAttribution: ZenDoodles commentedComment #75
star-szrComment #76
star-szrD'oh, I missed a bracket. This should pass.
Comment #77
star-szrComment #78
star-szrLooks like this needs another reroll.
Comment #79
star-szruser.test
has now been split up into many smaller test files undercore/modules/user/lib/Drupal/user/Tests
.Here's a reroll. No code changes, just moved the test to its new home.
Comment #80
star-szrHere's a start at obfuscating the user IDs. I also tried drupal_get_token($uid), but that passed manual testing and failed automated testing. If we do stick with the method in this patch, would it make sense to break this out into a function in
user.module
since it is repeated 5 times?@xjm also mentioned in IRC that someone at the DrupalCamp Twin Cities core contribution sprint had a suggestion for an additional approach to validation. Paraphrasing: When creating new accounts, add validation so that if your username is an email address, it must also match your email address.
Comment #81
star-szrForgot the interdiff for #80.
Comment #82
star-szrAnother update:
testUserPasswordResetDuplicateUsers()
test because we are no longer allowing new registrations that would create username/email conflicts.Comment #83
star-szrI'm thinking now that perhaps there should be two different queries here. For new registrations, use a db_or() to check both user fields, for existing users just check the relevant field. This would eliminate two queries for new registrations.
It would also eliminate this ugliness.
Comment #84
star-szrSorry for the noise folks! I went ahead and made the change proposed in #83. I realize now the validation was very similar to this back in #2, minus the check between registered and non-registered users.
Comment #85
adharris CreditAttribution: adharris commentedI got sidetracked away from this issue, but actually just had this issue come up legitimately on one of my sites. We decided that allowing one user to use an email address that is not their own was not desirable for our use case, so we added validation to the user form so that if the user name is a email, it must be the email associated with that account. This allows us to avoid this issue cleanly, and assert the user "owns" the email they are trying to use as a username.
To me, this seems like a better way than just checking against existing users, but I might be missing a valid use case for some people.
Also, what happens in the existing patch if a user creates an account with foo@example.com as the username, and then later someone registers an account with that email? It seems that that would create this duplicate user situation as well.
Comment #86
star-szr@adharris - The approach you mention in your first paragraph was touched on in #80, and should certainly be considered.
The current patch validates that any new users registering cannot use a username OR email that is not already registered as a username OR email. So in the example you gave, the person who tried to register with an email of foo@example.com would not be allowed to register with that email since foo@example.com was already used as a username. If foo@example.com was registered first as an email, then a second user cannot use that as their username. This does not affect existing users, and there are tests to verify that existing users are not forced to change their email address or username.
Also… rerolled.
Comment #87
ZenDoodles CreditAttribution: ZenDoodles commented#86: 1359718-86.patch queued for re-testing.
Comment #88
star-szrAnother reroll for #1499596: Introduce a basic entity form controller and #1184272: Remove deprecated $conditions support from entity controller.
Comment #89
star-szr#88: 1359718-88-tests.patch queued for re-testing.
For some reason I'm seeing two of the assertions failing twice in the test-only patch, let's try that one again.
Comment #90
star-szr#88: 1359718-88-tests.patch queued for re-testing.
Comment #91
star-szrSorry for the noise, not sure what's up. 1359718-88-tests.patch on first test showed 8 fails (should have been 6), now testbot seems to hate it.
Comment #92
star-szrRerolled.
Comment #93
Rob C CreditAttribution: Rob C commentedAny update on this? Feature freeze is getting closer and closer... (I'm creating a small inventory with possible wanna-haves, just like this one.) Thanks!
Comment #94
star-szrThis needs another reroll, I'll work on that in the next few days. I think this could still get committed after feature freeze though.
Comment #95
webchickNote that this is just a bug, not a new feature, so we can commit it at any time.
Comment #96
Grayside CreditAttribution: Grayside commentedSeems related to, and potentially conflicting with #849602: Update 'username' theme template to use 'view label' operation.
Comment #97
Rob C CreditAttribution: Rob C commentedGreat Cottser! And got it webchick, but i wonder about this (and couple things more), because:
I like this patch, but i wonder if we can implement some configurable option? Just thinking about user cases where this could be an issue / flexibility. I already demo'ed hefoxed my demo site where i render a config option called:
"Prevent identical username and e-mail address". (description: "Enable this to make sure people do not submit identical username and e-mail address during registration.")
(In length of that idea we could also create some function to parse accounts to scan for usernames where this is an issue and force them to rename their account.) (maybe can do this in contrib space)
See this issue for a link to screenshots, demo page, lots of details.
#1837054: [META] Refactor account workflow (and config)
This all also made me think of some new options, the one related:
"Prevent people from using their e-mail address in the "username" field during registration."
I wonder if an issue about this exists, if not, i can create a patch of what i have working already. (that's concept patch-stage, but working)
[edit: fix oopse]
Comment #98
star-szrThanks for the clarification, @webchick!
Here's the rerolled patch.
Comment #100
star-szr#98: 1359718-98.patch queued for re-testing.
Comment #102
xjmSee #1812636: Remove deprecated $form_state['clicked_button'] for the test failure.
Comment #103
YesCT CreditAttribution: YesCT commentedtagging.
Comment #104
YesCT CreditAttribution: YesCT commentedupdating issue summary
Comment #105
star-szrThanks @xjm and @YesCT! I'll take a look at updating the patch over the weekend, unless someone else wants to tackle it sooner :)
Comment #106
star-szrHere's the revised patch, just updates clicked_button to triggering_element.
@YesCT: I looked through the issue summary, what is the interdiff for? The past handful of patches have just been rerolls. Attached an interdiff here for the heck of it.
Comment #107
YesCT CreditAttribution: YesCT commentedInterdiffs dont make sense sometimes... something about merges ..
But as a general rule they are super helpful for allowing someone to review something.
You'll get more participation when you provide them. :)
Comment #108
star-szr#106: 1359718-106.patch queued for re-testing.
Comment #110
star-szrI'll reroll this.
Comment #111
Grayside CreditAttribution: Grayside commentedThis issue exposes the fact that a given email address is in use by a user on the site. I can't think of anywhere else that currently happens, and does seem like a gray area. Once you have that information, you can try to see if there are any users that have the local name of their email address as their username on the site.
Comment #111.0
Grayside CreditAttribution: Grayside commentedUpdated issue summary with remaining tasks to make it easier for new people
Comment #112
star-szr@Grayside - For that issue, see #1521996: Password reset form reveals whether an email or username is in use.
Comment #113
star-szrUpdating tags per issue summary, thanks @YesCT!
Comment #114
star-szrStraight reroll, no changes to the patch.
Comment #115
Grayside CreditAttribution: Grayside commented#112/@Cottser:
That issue is specific to the new password form, but you are right, the type of exposure is the same.
However, where that issue is simply going about the business of not admitting to any specific email address, this issue is relying on doing so to create an actionable UI.
Comment #116
andymartha CreditAttribution: andymartha commentedIt took a while to read everyone's comments and understand this issue, but I can confirm some things:
On a fresh Drupal 8.x-dev install from March 6th, 2013, I:
1) created a user with username b**@gmail.com and email a**@yahoo.com
2) created a user with username a**@yahoo.com and email b**@gmail.com
On the request new password screen at user/password, if you requested the password for username b**@gmail.com it will send the password to the email of b**@gmail.com (which in this case is a different user).
After applying patch 1359718-114.patch in #114 by Cottser, on the request new password screen at user/password, if you requested the password for username b**@gmail.com, Drupal will stop and show a confirm screen "There is a username conflict with the email address b**@gmail.com. Please select which account password to reset." Also, after applying the patch, if I completed step #1 above, I am blocked from completing step #2 above. See screenshots. Hopefully the screenshots will add some clarity to this issue :)
Comment #117
snowpeas_60609 CreditAttribution: snowpeas_60609 commentedembedding screen shot
Before Shot
Before Shot 2
After Shot
After Shot 2
Comment #118
designfitsu CreditAttribution: designfitsu commentedadding crop image for issue summary
Comment #118.0
designfitsu CreditAttribution: designfitsu commentedRemove interdiff task, we've just been chasing HEAD and test changes recently.
Comment #119
Dries CreditAttribution: Dries commentedThanks for all the work on this. I like everything about this patch, except the new 'Request new password' screen. The UI appears to show the username associated with an e-mail address. This could be a security breach in my opinion, as it could potentially be exploited to identify who is behind a specific username. Thoughts on this?
Comment #119.0
star-szrIssue summary is updated with issue summary template
Comment #120
star-szr@Dries - Thanks for reviewing this.
With the latest patch, the only time the "Choose account" UI is displayed is when an email address is entered in the "Username or e-mail address" text field and the entered email address matches two users. Even then, the UI only displays the email address the user entered, no username information (other than exposing that a user with a username matching the entered email address exists). Earlier patches used the usernames as keys in the form but those were obfuscated in #80.
So as far as I can tell we are not introducing any security regressions, see #1521996: Password reset form reveals whether an email or username is in use for some privacy concerns around the existing password reset form that would apply here as well.
Someone at our sprint also suggested another possibility for handling the edge cases which I don't believe has been brought up in this issue - just email both users. Not sure what I think about that just yet.
Comment #121
star-szr@adharris articulated this way better than me in #68 :)
Edit: added quote.
Comment #122
star-szrLooking at the screenshots, it probably doesn't make sense to have the 'Cancel' button first on the "Choose account" form. CNW for that, will reroll this weekend.
Comment #123
YesCT CreditAttribution: YesCT commented@snowpeas_60609 thanks for embedding those screenshots. It really helps speed reviewing.
Comment #124
star-szrRe-titling for clarity. Thanks @designfitsu, @andymartha, and @snowpeas_60609 for moving this forward :)
Comment #125
star-szrTrying again.
Comment #126
star-szrAdded a weight to the Cancel button, new patch and screenshots:
Comment #126.0
star-szrCorrect path to request new password form
Comment #126.1
star-szrUpdating UI screenshot
Comment #127
star-szr#126: 1359718-126.patch queued for re-testing.
Comment #129
YesCT CreditAttribution: YesCT commentedhttp://drupal.org/patch/reroll (how to reroll)
Comment #130
star-szrThanks @YesCT! Unassigning so this can be rerolled.
Comment #131
rbayliss CreditAttribution: rbayliss commentedDrupalcon Portland sprint: working on a reroll.
Comment #132
rbayliss CreditAttribution: rbayliss commentedA reroll, also changes uses of drupal_hash_base64() to Crypt::hashBase64().
Comment #133
Gaelan CreditAttribution: Gaelan commentedComment #135
star-szrThanks @rbayliss! I tried applying #132 locally but it needed another reroll, see attached.
Comment #136
PanchoSorry for chiming in after 134 comments, but I believe that this approach doesn't really cut it.
@Dries stated in #119:
@Cottser answered in #120:
Now while it is true that we're not introducing a completely new privacy regression, we're adding another instance of the same privacy breach. While we already need to get past the existing privacy breach, we can't reinforce it at another place. This IMHO isn't acceptable.
It really doesn't help that it's only displayed in specific situations if the specific situation can be diligently induced by anyone.
Also, while already possible, this is an open invitation to reset the password of someone else and exhibits our weak security level at this specific point.
At the same time, this introduces considerable complexity (additional code, a multi-step form) to solve an edge case which actually shouldn't exist, so it is a quite elaborate stop-gap which doesn't solve any of the underlying consistency (uniqueness) and validity (spoofing) problems.
Please don't be offended by my rant, I really feel sorry for the amout of work that already went into this, but I really can't imagine seeing this in D8 core. Might be okay as a D7 stop-gap, but I'd rather propose digging a bit deeper #2014185: Check usernames that are email addresses more rigidly, only allow if matches email to get the underlying deficiencies eradicated.
Comment #137
star-szrThanks @Pancho, great to hear some feedback. Working on this issue for over a year has taught me a lot about the changes in Drupal 8, so regardless of what happens with this patch I'm not worried and won't be offended. I do want to clear up one thing though:
I don't think this is true - the patch here prevents any new user registrations that would meet these conditions. The multi-step form and (most of) the additional code are there for the sole purpose of handling existing data.
Edit: clarified last paragraph.
Comment #138
PanchoHey @Cottser,
and thanks for not being offended!
I need to clarify and specify my statement about the privacy aspect:
The patch really doesn't introduce an additional instance of a privacy breach that wouldn't have already existed. You even takes a long way to not expose more data than necessary.
Still it makes fixing the preexisting privacy problem not just a bit harder, it even makes it impossible.
I need to explain this in some length:
If someone tries to register an email address that has already been registered before, we somehow have to reject this registration. And it's really hard to reject a registration without disclosing the reason. But let's look into the actual cases:
The fact that email address already exists can only occur in the following situations:
So while for the user in case 1 it is nice to be reassured that the account already exists, it's simply not worth the privacy breach, especially because it is possible to inform the user via the existing email address that s/he can access.
Same holds for the second case where the address has changed the owner: the new owner has access to the email account.
Now the third case is harmless and getting immediate feedback that the address is already registered would be very nice, but again is not worth the privacy breach. What we can do is display the entered email address and hope the registrant sees the typing error. As in the latter two cases the registrant doesn't have access to the entered email address.
The latter two cases are dangerous and any disclosure has to be avoided.
So in order to stay on the safe side, we have one possibility to not disclose any information:
Don't directly notify the registrant that the account creation is impossible! Generally just give feedback that an email has been send to the given address. And yes, we can always send the email, because we can assume that only legitimate account owners get the email and thereby get informed that possibly someone else tried to register with his/her email address.
Now what changes does this patch introduce to this situation? Imagine your patch is committed:
Now we're checking the chosen username against existing email addresses. Now we somehow need to inform the registrant that the chosen username is not possible. We can only do that by email, but in this case things are diffferent:
If we're sending the email to the email address of the preexisting account (the username of the newly registered account), the new registrant gets it only if s/he is legitimate owner.
But let's rethink this from the perspective of the two "dangerous" registrants. Imagin, they entered 'bill.gates@microsoft.com' as their username and 'spammer696@xxxhost.ru' as email address. The email address is both valid and can be expected to be unknown to the system. So if they don't receive an email at 'spammer696@xxxhost.ru', they know that the registration has failed and if they know only a bit about Drupal, the can induce that this is because 'bill.gates@microsoft.com' is already registered.
Goal accomplished: Now they know Bill Gates is user of this website and can add his email to their targeted address list.
Now this is only about the privacy problem which is indeed getting worse by this patch.
Add to that the fact that this doesn't help with spoofing.
And yet another aspect would be the fact that now that you're doing this here:
means anybody can now abuse your email address as username in order to keep you from registering with your own email address.
In spite of the very best intentions, all of this unfortunately really suggests that this approach is broken by design. Still we probably had to go this way to eventually come to the insight that it's simply not possible to alleviate this problem just a little bit, without this or the other way making it even worse.
I'm really tempted to mark this approach "won't fix", and restart on #2014185: Check usernames that are email addresses more rigidly, only allow if matches email.
Still I'm not claiming to be 100% sure that the proposals over there fully work out. They simply seem to be slightly more promising.
Comment #139
star-szr#2014185: Check usernames that are email addresses more rigidly, only allow if matches email hasn't budged so tagging this for another reroll.
Comment #140
ZenDoodles CreditAttribution: ZenDoodles commented@YesCT, @Les Lim, @SeanKelly, and I discussed this at a code sprint (in Twin Cities) and we believe this issue and #2014185: Check usernames that are email addresses more rigidly, only allow if matches email are distinct problems. Let's move forward with this as is... rerolled of course.
Comment #141
YesCT CreditAttribution: YesCT commentedI think fixing the last part of comment #138
in #2014185: Check usernames that are email addresses more rigidly, only allow if matches email makes sense. Lets keep that separate from this.
Comment #142
YesCT CreditAttribution: YesCT commentedSummarizing.
Prevent people registering with a username that matches some user's existing email address.
Prevent people registering with a email address that matches some user's existing username.
When requesting a password reset, and the info entered matches both a username and an email address, ask which. See #126.
Comment #142.0
YesCT CreditAttribution: YesCT commentedadding related issue (to motivation)
Comment #143
ZenDoodles CreditAttribution: ZenDoodles commentedYet another reroll
Comment #144
ZenDoodles CreditAttribution: ZenDoodles commented*d'oh*
Comment #146
meba CreditAttribution: meba commentedI somewhat agree that creating this UI is problematic. It is now possible to create duplicate users and if we land a patch that disallows that we should just be fine. Existing sites are broken and will simply continue to be broken. If people actually suffer by this we would see forum posts on stackexchange or drupal.org. It's better to not be able to reset your password and have to contact administrator rather than exposing yet another UI.
Comment #147
garphy CreditAttribution: garphy commentedI rerolled the last patch in #143
Comment #149
star-szrI think we may have lost some changes between #135 and #143:
#135: 5 files changed, 280 insertions, 61 deletions.
#143: 5 files changed, 310 insertions, 16 deletions.
Comment #149.0
star-szrupdated remaining tasks. Tried to clarify the motivation and correct grammar.
Comment #150
jbloomfield CreditAttribution: jbloomfield commentedAttempting patch reroll from #135
Comment #151
jbloomfield CreditAttribution: jbloomfield commentedRe-rolled patch. I ran a local SimpleTest and it failed on the mail() function but I think that is because I don't have a local mail server setup.
Will see how the online test goes.
Comment #154
jbloomfield CreditAttribution: jbloomfield commented@Cottser
Looking at the validate() function in the /core/modules/user/lib/Drupal/user/AccountFormController.php file.
Line: 305
I am getting an error that it is trying to convert a FieldListItem to an int as
$account->id()
returns NULL when the user is creating an account.So, I tried the below which removed the error.
I haven’t changed the patch as I wanted @Cottser to take a look and get his thoughts.
Comment #155
jbloomfield CreditAttribution: jbloomfield commentedChanged status to Needs Review.
Comment #156
jibran#111317: Allow users to login using either their username OR their e-mail address is pending on this one now.
Comment #157
damiankloip CreditAttribution: damiankloip commented@pancho is totally right in #138 I think, this approach is just not sufficient. This would not stop me registering yourname@emailaddress.com as my username, when you came along to register an account, you would not be able to because I had stolen your email address as my username. This is why #2014185: Check usernames that are email addresses more rigidly, only allow if matches email is more important to start with IMO.
Plus this patch is really out of date.. :)
Comment #158
mgiffordJust adding related issues...
Comment #159
Sutharsan CreditAttribution: Sutharsan commentedReroll of #151. Including several required changes due to changes in $form_state, select queries, deprecated and removed functions. The interdiff contains the changes after the git reroll.
[edit] The #154 comments are not included.
Comment #160
mgiffordComment #162
Sutharsan CreditAttribution: Sutharsan commentedRerolled the #159 patch
Comment #164
mgiffordWhat happened to core/modules/user/user.pages.inc?
Comment #165
jhedstrom@mgifford #2407489: Remove user.pages.inc.
Comment #166
subhojit777Comment #167
subhojit777Comment #170
Manjit.SinghComment #172
subhojit777Thanks @Manjit.Singh for working on the patch. There were some minor changes needed to do.
Comment #173
subhojit777Comment #175
subhojit777Comment #177
Anonymous (not verified) CreditAttribution: Anonymous at Druid commentedThis should fix tests there was used drupalPost where it seemed like the intended method was drupalPostForm
Comment #178
subhojit777I have tried the approach in #177. It removes the exception but still there are some tests failing. I am working on it now. Please give me some time. Drupal 8 noob here :)
Comment #179
Anonymous (not verified) CreditAttribution: Anonymous at Druid commentedif you check the method drupalPost() you can see its third argument is array of the HTTP POST values not the submit name
Comment #180
subhojit777@b0unty yes. I am working on it locally. I have tried changing
drupalPost()
todrupalPostForm()
. It fixes the exception messages, but still there are some tests failing. I am working on it.Comment #181
subhojit777@b0unty For example this one is failing
$this->assertText(t('The name @name is already taken.', array('@name' => $edit['name'])), "A user cannot be created when their username matches an existing user's email address.");
inUserRegistrationTest::testRegistrationConflicts()
.Comment #183
Anonymous (not verified) CreditAttribution: Anonymous at Druid commentedtested manually: created user a with email q@q.fi, created user q@q.fi with email b@b.fi. went to /user/password, entered q@q.fi. did not prompt the choose element.
anyways heres patch that fixes most of the exceptions from passwordresettest
Comment #185
subhojit777@b0unty This is the second time you are hijacking my issue :) Please give me some time. I am very close to the problem.
P.S. See IRC :)
Comment #186
subhojit777Rolling new patch. No interdiff uploaded because I was working separately. The patch uploaded by @b0unty in #183 resolves the exceptions, but does not fixes the issue.
Comment #188
subhojit777Comment #192
subhojit777Forgot to remove redundant code.
Comment #193
subhojit777Comment #197
subhojit777Comment #199
subhojit777Comment #200
subhojit7771. I guess the patch in #199 will fix the tests failing in
Drupal\user\Tests\UserPasswordResetTest
.2. Do we need to retain this test
in
Drupal\user\Tests\UserRegistrationTest
. According to this issue we can create username that matches with existing user's email address, or vice versa.3. Tests failing in
Drupal\system\Tests\System\SiteMaintenanceTest
is not yet fixed.Comment #202
Anonymous (not verified) CreditAttribution: Anonymous at Druid commentedWhy use it this way and not use the ->isAuthenticated method?
$this->t(
if ('a' == 0), would be true, should use strict check.
why are we creating a function that is deprecated when added?
Comment #203
subhojit777@b0unty Thanks for the review. I will take care of the things that you have mentioned along with the failing tests.
As per #202.4, I was going to check the issue history and see in which patch the function was introduced - what was the reason. My opinion, we can remove that function as the default
user_pass_reset
'sbuildForm()
does what is required. We dont have to change it.Comment #204
subhojit777Comment #205
cilefen CreditAttribution: cilefen commented#2502021: Unhandled exception when trying to register a duplicate user
Comment #207
RavindraSingh CreditAttribution: RavindraSingh as a volunteer and at Srijan | A Material+ Company commentedUse '@' instead of using '%' as a placeholder for email field.
Follow the common standards for securing code. as mentioned above.
Comment #208
subhojit777@RavindraSingh I changed '@' to '%' because the tests were failing. Looks like somehow it got changed in the patch. Anyways is there any specific reason for the change you are suggesting - because both of the formatters are escaped to HTML there won't be any security issue.
Comment #209
subhojit777Comment #210
Anonymous (not verified) CreditAttribution: Anonymous at Druid commented#202.4 has not yet been addressed.
Comment #212
subhojit777I see that
user_pass_reset()
has been introduced in #159. I have checked with the defaultuser_pass_reset
form, and I think we are better off with that, we don't have to alter it.Comment #214
subhojit777Comment #216
subhojit777Comment #218
subhojit777This test in
UserEditTest.php
conflicts with the purpose of this issue, hence I am removing this test.Comment #219
subhojit777Comment #220
Anonymous (not verified) CreditAttribution: Anonymous at Druid commented$this->t,
just a nit. could not review fully so not setting it to needs work.
Comment #221
star-szr#218 are you sure? It's been a while since I've worked on this issue but that test was added for a reason.
Comment #222
subhojit777Thanks @Cottser. I am checking the issue queue again where that test was added. I thought that the test was already in the system (since the system allowed duplicate username and email address earlier), so I removed it.
@b0unty Thanks for the review.
Comment #223
star-szr@subhojit777 I can help with that a bit see #82.4
Unless the patch has drastically changed directions but at a glance it doesn't seem to be the case. I haven't kept up with this issue recently.
Comment #224
subhojit777Comment #229
subhojit777@Cottser thanks for pointing that out
Comment #230
Anonymous (not verified) CreditAttribution: Anonymous at Druid commentedthese have been set to a variable before why not use it?
could use a comment to tell why we check this?
$this->logger seems to exist in this methods scope. why are we not using it?
Comment #231
subhojit777@b0unty Thank you! I am not sure about the third, I guess it was not working. Will work on rest of the things.
Comment #232
subhojit777Comment #233
subhojit777Comment #234
Anonymous (not verified) CreditAttribution: Anonymous at Druid commentedseems good to me.
Comment #236
Anonymous (not verified) CreditAttribution: Anonymous at Druid commentedComment #237
subhojit777Comment #238
subhojit777Comment #239
subhojit777Comment #240
subhojit777Comment #242
heykarthikwithupatch no longer applies.
Comment #243
Manjit.SinghComment #244
royal121 CreditAttribution: royal121 commentedPlease check the patch.
Comment #246
Manjit.Singh@royal121 why did you attach .css.gz in patch file ? I guess that is why testing is failing.
Also there is huge difference in the file size, compare #238 and #244.
Comment #247
kostyashupenkoReroll of #238
Comment #250
aerozeppelin CreditAttribution: aerozeppelin at California State University San Bernardino commentedRerolled patch #247.
Comment #263
smustgrave CreditAttribution: smustgrave at Mobomo commentedThis issue is being reviewed by the kind folks in Slack, #need-reveiw-queue. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge require as a guide.
This will need to be rerolled for 10.1
Once that's done it still needs security review it seems.
Comment #264
karishmaamin CreditAttribution: karishmaamin at Specbee commentedTried re-rolling patch against 10.1.
Comment #265
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #266
Prem Suthar CreditAttribution: Prem Suthar at Srijan | A Material+ Company for Drupal India Association commentedRe-roll the #264 Patch For Fixing the Custom Commands Failed.
Comment #267
Prem Suthar CreditAttribution: Prem Suthar at Srijan | A Material+ Company for Drupal India Association commentedInterdiff Between The #264 - #266.
Comment #268
Prem Suthar CreditAttribution: Prem Suthar at Srijan | A Material+ Company for Drupal India Association commentedBy Mistake Wrong Interdiff Posted So i remove that Upload the Correct one.
Comment #269
Rassoni#266 user.Module files are missing, but in Interdiff that file user differences mention.
#264 patch applies successfully. fixed coding standard.
Comment #270
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #271
RassoniComment #272
RassoniFixed Custom Command issue and #269 patch failed to apply.
Comment #273
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #275
Ajeet Tiwari CreditAttribution: Ajeet Tiwari at OpenSense Labs for DrupalFit commentedresolved the error of custom commands of the patch uploaded in #272.
Comment #276
apadernoComment #277
Ajeet Tiwari CreditAttribution: Ajeet Tiwari at OpenSense Labs for DrupalFit commentedresolved the issue of custom command failure.
Comment #279
RassoniComment #281
poker10 CreditAttribution: poker10 at ActivIT s.r.o. commentedI think the approach used in #272 would needs to be reconsidered and changed, as it practically nullifies the effect of the #1521996: Password reset form reveals whether an email or username is in use. E.g. it is removing the universal
If %identifier is a valid account, an email will be sent with instructions to reset your password.
message. Using this patch the system would again reveal whether an email or username exists.Other that that, the rerolls #275 and #277 are incomplete, so be aware, as these patches are wrong. @Ajeet Tiwari please pay attention while rerolling the patches, that none of the previous code is lost. Thanks!