rubygems.org
rubygems.org copied to clipboard
Investigate email casing
We had a user contact us via support to say that they weren't receiving an email confirmation. Investigating, it looks as if the system is storing their email address downcased. Fine, great.. except that the username portion of an email address (the bit before the @
) technically is case sensitive.
This is likely fine, as we seldom see them, but I wonder if we should at least add a UI warning, since users /may/ not receive the email that they expect?
except that the username portion of an email address (the bit before the @) technically is case sensitive.
Yes, username part should be kept as is.
I believe Postgres is case insensitive for string queries by default. Most email providers are also not case sensitive.
On Sat, Aug 11, 2018 at 12:21 PM Aditya Prakash [email protected] wrote:
except that the username portion of an email address (the bit before the @) technically is case sensitive.
Yes, username part should be kept as is.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/rubygems/rubygems.org/issues/1763#issuecomment-412285414, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHQQkW2VdzS6RXU110EAO0fJPmRP2Sfks5uPwRzgaJpZM4V4dY9 .
--
David Radcliffe
@dwradcliffe it doesn't appear to be set up that way, based on what I'm seeing.
irb(main):004:0> User.find_by_email("[email protected]")
=> nil
irb(main):005:0> User.find_by_email("[email protected]")
=> #<User id: 51537, email: "[email protected]...
This /might/ be simply an edge case, as the user in question was asking for help after not receiving their confirmation email, a common enough complain that is a larger, ongoing issue. I'm dubious this is a pressing concern, but wanted to at least get it down in an issue.
👍 If we need to make an adjustment that's fine but let's make sure we're careful to not expose a security problem by allowing case sensitive emails.
I've been previously recommended to store emails as lowercase for authentication purposes, but to store them exactly as the user typed them and use that version for sending any emails.
so which way have we decided to go in with this issue? Maintaining different email to send mails or just to add a UI warning when the user puts email in uppercase? @kerrizor @dwradcliffe I can pick this up if we know what we want.
@anuragaryan Here's a plan.. @dwradcliffe thoughts?
- [ ] remove case-normalization from email in the User model (IE - accept whatever the user types in)
- [ ] add a msg to the UI about emails being case-sensitive (either static or triggered to appear when the user enters a mixed-case email) to
- [ ] sign-up
- [ ] login
- [ ] password/email recovery
- [ ] ???
@dwradcliffe if you've nothing else to add, I'm starting on this based on @kerrizor 's plan.
Based on some previous experiences, having using lowercase emails is very helpful for the majority of users; as that's what they've come to expect due to how all the major providers deal with emails. I wouldn't suggest going with removing case normalization because you'll have cases like people opening the autocorrect capitalizing the first letter, then opening it later without autocorrect and not being able to login and being very confused. I would still recommend the two-fold solution:
- Store email as the user typed it, send emails to this version.
- Store lowercase email and use it for all authentication purposes.
@obahareth at DB side it is not needed to be stored twice, it is enough to create "lowered" index:
CREATE UNIQUE INDEX lower_case_email ON users ((lower(email)));
SELECT username FROM users WHERE lower(email) = lower('[email protected]');
@simi wouldn't [email protected]
and [email protected]
will be considered same then?
@anuragaryan depends on query then (if using lower(email)
or email
).
@simi That's correct, what I meant was if some mail host allow case sensitive emails, then [email protected]
and [email protected]
can be two valid email, belonging to two different people. If we lowercase index them both, how can we differentiate between the two?
We should store exactly what is entered at signup, and send emails using that exact casing. However we should enforce uniqueness on lower(email). This might prevent someone from signing up (they would be using a rare email provider) but it will ensure that we don't open a huge security hole for most email providers.
@dwradcliffe @simi can we get the PR reviewed?
@anuragaryan I have revived your commit and opened PR at https://github.com/rubygems/rubygems.org/pull/4200. Sorry for the massive delay in here. Feel free to review.