Should I store duplicate email addresses? - node.js

Just thinking about my registration flow for my Nodejs/MongoDB app and wondered whether I really need to check if email addresses are already in the database when users register.
I make my users verify their email address by clicking on an email that I will send to them. They must do this before logging in at all. Once they do click on this link then I will mark that email as verified in the database. With this in mind, I'm thinking that it doesn't really matter if someone registers with the same email address (for whatever reason) as it won't be marked as verified unless they can access the email account.
I'm wondering however if it will impact on performance when it comes to searching for users in the database via email address. For example, users login using email address. Would it be advisable in this case to create an index on both email and verified?
Have I overlooked something that could potentially be a security flaw?

Performance-wise it will probably not matter a great deal (you probably already have an index on the email field), but I don't think you should allow it anyway.
For one, it has the potential to add junk to your database. Secondly, it would allow existing users to create—by mistake or not—a second account with the same e-mail address, which could cause all sorts of issues.
You don't give a specific reason for wanting to allow duplicate e-mail addresses, but a duplicate check isn't really all that time-consuming to implement (you could also consider a unique index on email so the database will throw an error when someone is trying to reregister an existing address).

Related

Best practices for passwords on registration?

I have a website which users register an account. On the registration field, the form fields are:
Name
Email
Confirm email
Username
But there is no password field. When they hit submit, they are emailed a password which is very complex, such as LHJVjhwnv%uu5 or RbWM9!jeDZUQb.
I have appealed to my developer to instead make it so that the users can set their own password on the registration form. To confirm that password on the form, and then be sent a confirmation link to their specified email. Then this way they can at least log in to their account and verify their email via confirmation link. Or if they didn't, every time they log into the site it could remind them to verify their email etc or else they can't do much on the site (example). This way even if they don't get the confirmation link, they can still update their account email to a different email and have it resent. At least at this stage, they can log into their account, instead of not at all.
The response I have received from the developer is as follows
"The problem with providing the password on registration is that
you'll have loads of fake accounts. So people that just register with
a non-existent email address. At least with the email validation
you're proving the user exists, to a certain extent. If they register with the wrong email, they can just re-register."
I'd like to ask you all if the current approach the developer has employed is acceptable?
If not, what are some good reasons I could use to convince the developer to change?"
I've tried to explain the following
Every day there are 9-10 people who register and then directly use the "password reset" form right after. This form involves them putting in their email address that they signed up with, and then it emails them a link to SET a new password. So if they are setting a new password anyway, why not just have them set it in the first place on the registration form? Why would there be 9-10 people every single day using the password reset field, directly after registration? I'm pretty sure its because they are seemingly struggling with these complex passwords (which I am not against) that are being emailed to them and are missing a key or character, or do not seem to be aware of copy/paste or something like that. If they could just set their own password the first time around, they wouldn't need to run to the password reset field right after because of their emailed password not working. I thought it was weird how everyday theres always password reset emails. Not for everyone, but a good 9-10 people a day ever since I started using Mandrillapp to track the outgoing emails. This is backed up by the next point.
Every day there are at least 2-3 people who fill out the contact form indicating that the password they received is not working. Could all be avoided if they just could set it on their own. There may be even more that just don't bother contacting.
Out of nearly 8000 accounts, 50% have never logged in. My strong suspicion is that the Registration email containing their password goes to their junk folder/spam folder. This is despite me having proper SPF, DKIM, etc setup. 2 months ago, I decided to start using Mandrill to send mail to ensure it goes to the inbox, but still there's at least 1-2 people/day that say that they did not get their email.. which perplexes me. If they could define their own password, they wouldn't have to worry about waiting for their password via email, or not getting it entirely. This just further highlights my initial concern.
Thank you for your time!
I assume you already have a working password-reset page in place, so you can use just the same code to do the registration:
Let the user register with his email.
Send a link with a token to the user, a hash of the token is stored in the database.
If the user clicks the link and if the token is valid, welcome him and let him enter his own password.
This is exactly what you already have for password resetting, your site becomes no more (un)secure because an attacker could as well use the password reset function.
Of course weak passwords are a problem, so rejecting weak passwords is a must. Again this is the same you would have to do on the password-reset page. For password-resets you wouldn't send plaintext passwords neither.
Unconfirmed accounts can be deleted after a certain period, it means the user didn't do anything with it. If necessary the user can register again. This only works if the user is not allowed to login before doing the confirmation, what supports the procedure above. Of course it depends on the website if this confirmation is that important though.
The main reason not to send passwords in a mail is security: Mail isn't a secure medium. If you put a password in there, then many people can see it - consider allowing people to use your service without any kind of password instead to understand what I mean.
The main drawback of allowing people to chose their own password is that 95% will use 123456 or password.
Most big sites use this approach to balance security, business needs and comfort:
Allow user to set their own password. Reject the most simple ones (there are libraries for this). Note: Complex password rules drive customers away.
Send a confirmation link via mail.
Don't allow login until the link has been clicked.
If they try to login anyway, tell them that they have to click the link first plus provide a "send confirmation link again" link in case the first mail was lost.
I have appealed to my developer to instead make it so that the users can set their own password on the registration form....
This opens you up to a plethora of weak password and reuse attacks. Reuse has been empirically studied and reported between 50% and 76%. Other academic studies have stated nearly all users (almost 100%) reuse passwords.
So assigning passwords helps with major practical problems. After you assign the password, then you are subject to the same attack, though because a user may reuse the assigned password on another site.
...
I'd like to ask you all if the current approach the developer has employed is acceptable?
Yes, its acceptable as long as the password meets security requirements. I even prefer it, especially when user selected passwords are not checked against bad password lists.
Bad password lists are important because we know attackers use them. There are literally millions of passwords on them because of all the past breaches (did I mention password reuse is a pandemic problem?). The lists are easy to find, and one researcher recently released his list of 6,000,000+. See How I Collect Passwords.
Aaron is correct about email and plain text. You can actually place another security control to limit the exposure. Namely, require that your mail server use SSL/TLS or fail the connection.
Or, generate the password and display it to the user on the screen. Instruct the user to print the password so they don't forget it. I even tell my users to write them down and keep them in their wallet or purse.
The primary threat is a network based attacker attempting to gain unauthorized access to the server through weak/wounded/bad passwords. So an out-of-band/out-of-channel email is not too great a concern. And a lost wallet or purse is not too great a concern. The concern is the network based attacker guessing passwords or using {username,passwords} tuples from breaches of other sites.
Every day there are 9-10 people who register and then directly use the "password reset" form right after. This form involves them putting in their email address that they signed up with, and then it emails them a link to SET a new password.
OK, that's a security defect since the user can circumvent the security control.
For what its worth, I regularly use a random password generator to generate passwords for accounts. I don't even bother writing them down. When I need to access the account, I simply go through the Lost Password process.
That's how low value these things are to me. Every damn site wants a user to manage an account and password. I'm tired of expending the energy to manage all the accounts, so I don't even waste the cycles on it.
The problem with providing the password on registration is that you'll have loads of fake accounts. So people that just register with a non-existent email address. At least with the email validation you're proving the user exists, to a certain extent. If they register with the wrong email, they can just re-register
OK, so this is a different problem. BOT registrations are usually mitigated with a CAPTCHA. I've never really studied what to use for Real Users/Fake Accounts.
What is the benefit of a fake account? It seems to me the user is trying to get half pregnant. They either have an account, or they don't have an account.
Out of nearly 8000 accounts, 50% have never logged in. My strong suspicion is that the Registration email containing their password goes to their junk folder/spam folder. This is despite me having proper SPF, DKIM, etc setup.
Well, that's a different problem (that you should confirm through testing). This speaks to displaying the password for the user and telling them print the page.
There's a lot more to the subject of password management. You should read Chapter 7 of Peter Gutmann's Engineering Security.
I have appealed to my developer...
Finally, you are the boss. Fire the developer or contractor if they are not following instructions or coding against requirements. I'd be damned before I begged someone who I was paying for services.
Programmers are a dime a dozen, and you can find plenty of them at places like Rent-A-Coder. The Indians and Pakistanis work for next to nothing (under $10 USD per day in some cases). I don't know how they can work for so little and survive...

Should a user registration form indicate if an email address is already in use?

It seems pretty typical to limit user accounts to unique email addresses. So on my user registration form, I am doing email validation and returning a message like
An account has already been registered for foo#bar.com
Then it occurred to me that an attacker could use this form to determine information about my users. Is there an alternative way to provide validation messages to my users without compromising security? It doesn't seem to me there is any way around it.
For most kinds of sites, I would expect that explicitly hiding this information would be a poor user experience trade-off. The better solution is to use CAPTCHA to help prevent war-dialing of email addresses.
The exception would be in cases where an attacker is seeking out information about a specific user (rather than just trying to find "some account"). As an example, if your site caters to people who have a strong interest in anonymity, and there are attackers who have a strong interest in finding out if a specific user is using the site, then the approach should be different. My approach would likely be to send an email to the address indicating the "already registered" error. The user experience annoyance would be outweighed by the user's anonymity interest.
Rob Napier's answer is correct. You should decide whether your users actually need that anonymity at the cost of degraded UX (in most cases they wouldn't care).
Here's how some big names do it:
AWS: Error: Account with this email already exists.
Apple ID: This email address is not available. Choose a different address.
Cloudflare: A user with that email already exists (Code: 1079)
Linkedin: Someone's already using that email.
Stack Overflow: Forgot your account’s password or having trouble logging into your Team? Enter your email address and we’ll send you a recovery link.
Simply tell them they cannot use the email address they have supplied ? You don't need to give any more reason than that? If they know it's not their email they might still guess it's an existing address but you haven't confirmed that.
Or
How about telling them you've sent an email to that address and they need to confirm - even if you haven't.
I can think of one way: you could ask for an email address and then send the link for a one-time registration form to that email address. You might need a captcha in there to stop spam. If the email is already in the system it could send a message saying that they already have an account.
I think this is unnecessary tho, unless your website is especially secret, like a support group for abuse victims.
I don't think it is really possible to create an error message without indicating that the email address is already in use, as that is the point of the email address.
These are the options I see:
1) Display a not so clear error message like "Email address is invalid"
2) Accept the registration and inform the user about his earlier account via email (I would suggest that)
In any case you can improve security thru captcha codes and throttling requests by the same client. If you care that much about the privacy of your users, forcing a unique email registration is maybe not suitable for your site.
You can receive this error message if you have already an existing email alias with this email or user foo#bar.com.
You can check that if the email alias exists then you will have to first remove it and then try to create it.

Are reset password links a bad idea?

We have a password reset web application. The application sends out an confirmation code to an alternative e-mail. My manager believes it is not a good idea to include a link to the page were you have to enter the code.
I see his argument. However, the helpdesk has been overwhelmed with users who are confused about the process. I'm assuming this is because many our users browse using only one tab/window and navigate out of our web application to check their e-mail for the confirmation code.
My question: How should we approach this issue? I would like to alleviate helpdesk and, in turn, make the process pain free for our users. Any suggestions?
Clarification
He believes that we are doing the user a disservice by training them to click links from a sender that cannot be verified (in this case, it's an automatic message with a "no-reply" address). This, would in turn, make users more susceptible to phishing attempts which we've had a lot of issues with in our organization.
I think sending links is the standard way of doing it. If a customer is really worried about the integrity of this email account, he better gets that sorted out first.
Essentially you don't gain extra security by not sending the link, but you gain a lot of comfort. Just do it like everyone else - put it in there (time limited).
The only thing on the top of mind would be the option to have a unique identifier in the e-mail's subject an have the customers reply to that mail.
Then an automated script checks 'password-forgotten#mycompany.de' for emails with the subject 'Re: Forgot your password? [UNIQUEID]'. The script would then mail them their new password.
Since most users won't modify the subject when hitting "Reply To" and won't do a "Compose new mail" and enter the recipient address manually, chances are big, incoming mails to "password-forgotten" will have that UNIQUEID in the subject.
Plus helpdesk would only have help those that actually modify the email's "Subject". ;-)
There are security considerations, though. Maybe your manager might argue, that anyone might send a forged "Forgor your password" mail and set the "Reply-To" header to the attacker's address. The processing script has to intercept these attempts of forgery...
I see no reason why the link shouldn't be included, especially if the code is something like a hash because the chances of somebody cracking that are slim to none.
You could however, add an extra protection to the page where the code is being inserted and limit the number of tries to something like 3. For even more protection, send the email address to that page as well, and allow 3 tries per email address instead of 3 tries / IP, which can be easily bypassed.

Requiring unique email while not divulging emails of existing users

On a standard web signup form, users are required to have a unique email for the site.
if the email is already in use, a new user cannot be created with that email - but this opens op for exploiting this to find out, what emails are members of the site (at least check if a specific email is in use).
Making sure a bot cannot mass-query is fairly straightforward - but is there a way to avoid it entirely?
The best thing I can come up with is letting the user create process fail with an unknown error and shooting an email to the address in the background, explaining password reset procedures.
Am I missing a better option?
Update:
I want to avoid taking the new user out of the registration process for the 99.9% of the time, when the email is actually unique. So halting the registration process to wait for the user to click a link in an email is not a perfect solution, although maybe viable in some use cases.
Let the registration continue as normal, but in the confirmation email you should say:
"You allready have an accout bla, click here to cancel this registration, or continue with new registration and delete your current account"
That way, the spammers never know the better, and its very user friendly.
You could print on the web-page something along this:
An email is sent to you to verify the email address. Check your mail and click the included (shared-secret) link.
I.e. you probably have to verify the users email anyway, s.t. you can do it at this location of dialog ...
Many sites send a mail to the specified email address containing a randomly generated verification code and only accept the user registration once the user has confirmed they were able to read that mail and obtain the verification code. Usually the mail contains an URL that the user can simply click to confirm.
If you do that, all you need to do is make the confirmation email instead tell the user that they've already registered and explain the password reset procedure.
Whatever web development framework probably has a package that handles confirmation mails.
Note that you have to think about the case where a user had an email address and used it to register to your site, then they vanished without changing the address and stopped using the address, and another user now has the address and wants to register. There's no easy answer here.
ADDED: You add that you don't want a confirmation email so that the registration proceeds immediately. This requirement is contradictory with unique email addresses, because you don't know that the email address supplied by the user is legitimate until it's been confirmed, and there's no point in enforcing the uniqueness of a user-chosen string that just happens to be formatted like an email address (if you want a unique user name, it doesn't need to be formatted like an email address).
If you want to keep instant registration, you'll have to treat email addresses as just an untrusted text field until confirmed. That means that every action that requires your site to send a mail must bomb out if the user hasn't confirm his email address. The confirmation process remains pretty much the same, but now, if the address is a duplicate, the user must either be given the option to merge the two accounts (which sound difficult), or told that he must close one of the two accounts or change the email address associated with one of the two accounts.

Security risk in exposing email addresses and usernames?

Joomla has a built-in function on its login screen "I've forgotten my user name", so that you can type in your email address and the username is sent to you via email.
I was thinking of changing it so that the username was displayed on screen immediately, without any form of authentication. This would greatly reduce the friction for our users who are returning after a long while, but it would allow anyone to type in any email address and see the associated username (definitely not the other way around though).
Does this create any security risks? Is it a good idea at all?
The current implementation requires the user to own the email address, and read the resulting email, to retrieve the username.
Your implementation lets an attacker know immediately which username is connected to an email address. So if the attacker knows a person's username, it's possible to guess at email addresses.
Worse, suppose the attacker somehow knows the password but not the email address. After successfully guessing an email address, it's a reasonable guess that the password for the email account is similar to the password for your web site. So you've helped the attacker hijack the email account, which may contain more information about additional accounts, and so on.
In general, changing any security-related functionality to make things "easier" than the standard implementation probably incurs a security risk. +1 for researching via SO before implementing!
At first glance, it seems like a "bad idea" because you are allowing anyone to:
verify an account exists
confirm the association between a username and an email address
If usernames and mail addresses are treated as "private" information on your site and not already shared, then I would not implement the username lookup by email feature. In effect you are lowering the security bar by 1 factor:
Currrently, looking up the username requires both email address and the user's full mail credentials (so they can pick up the reply)
After the change, all they need is the mail address.
Perhaps more significantly, you create a privacy issue that would need to be addressed (as mentioned by #SoapBox).
But in reality, your site might already employ "username" as a public handle or nickname. And you may already have users publishing their email in their profiles. If this is the case, the username lookup doesn't leak any new information and you could argue no new security or privacy issues are created.
It would make it all a little too easy though, like publishing the script kiddies guide on how to hack my site:
Get a list of email addresses from your preferred supplier
Come to my self-service mail-to-username translation page and run the list through (simple script for this)
Launch dictionary attack on the site using the resulting list of usernames
Bottom line - I think you are best to leave this feature as-is.
I would say it is a slight security risk for your less savvy users. For a user with a weak password, particularly if it is related to their username or e-mail address, exposing their user name leaves them open to having their account hijacked. Other than that, I can't think of a reason it would be a problem. If the user has good passwords, it shouldn't matter at all.
I guess there is a slight anonymity concern. On a forum for example, I wouldn't want someone who "knows" me to find out my username without me telling them. In this case they could take my e-mail and get it. But whether that is an issue depends on your site and your user base.

Resources