62

Someone told me it shouldn't be possible for someone to detect if a certain email address is used by a registered user on a website. So, for instance, when the user asks to reset his password, you should say "Password sent" whether the email exists in the database or not. If not, people can use this function to check who is a member and also check validity of spam lists, etc.

But I noticed that Facebook says "E-mail already registered" if you try to register the same e-mail twice. Does this mean that conventions have changed; that informing the user is more important than revealing accounts?

Anders
  • 64,406
  • 24
  • 178
  • 215
forthrin
  • 1,741
  • 1
  • 13
  • 21
  • 2
    Why do you imply Facebook sets UX standards? I would rather suggest the opposite – phil294 Apr 15 '18 at 15:09
  • @phil294 It's one of, if not the, largest sites in the world and therefore one that withstands more attempts at its security in a single minute than most sites on the web do in a month, maybe a year. Much like Google sets many of the standards for web development with its documentation, so does Facebook, to a much lesser extent, simply because it needs to stay ahead of the engineering curve to survive being as big of a target as it is. For what concrete reason(s), (i.e. other than a bias against Facebook as a company), would you suggest the opposite? – Hashim Aziz Dec 07 '19 at 19:27
  • @Hashim I agree with you that Facebook surely sets security standards. But while the two are somewhat linked (see this very question), my previous comment was about *user experience*, not security issues. Facebook's desktop browser experience is far from modern and standard-y. But this is off topic and I should not have made the previous comment in the first place – phil294 Dec 07 '19 at 21:39

4 Answers4

60

It is a rather old tradition not to tell people whether specific logins exist or not. This is why Unix or Windows systems, when asking for user credentials, will respond to any error with a generic "wrong username or password" message. The idea comes from a rather old-fashioned vision of attacks: envision a bad guy who wants to enter a mainframe, and succeeds in getting his hands on a serial terminal plugged to the system, or maybe a telnet interface over a modem line. This attacker will be in a position of an online dictionary attack: he will try to guess a pair login+password which grants access. The administrative login names like "root" were usually better protected than normal user accounts (the "root" user was better at selecting strong passwords, or at least so it was surmised) so attackers would try to find normal user accounts, and, in particular, normal user account names.

Watching the movie War Games (from 1983) gives you a good idea of how things were.

Note the critical point: in the attack scenario above, the attacker wants to obtain at least an account, but could not get one under normal conditions, or even know who has an account.

It is now 2013, three decades after that movie. We have servers where everybody can register for free, and get an account. Obtaining one account is thus no longer an attacker's goal. Instead, the attacker will want to access specific accounts, with known identities. This is not the same situation. The context has changed. Therefore, old lore is not necessarily applicable.


Anyway, when a user tries to register on Facebook, he expects the process to work. At that point, the process may fail for only one plausible reason, which is an email address already used. It would be difficult to hide that fact from the user...

If we want to "protect" user email addresses, then the registration process must go thus:

  • User enters his alleged email.
  • An email is sent to that address, containing a one-time registration link; however, if the email is already registered, then an email is sent explaining that fact. No clue is written on the response Web page as to whether the email already existed in the system or not.
  • The user registers by following the link from the email.

Such a process would double as an email verification process, so that's kind of good. However, it has some latency (user must get out of the Web site, open his email reader, and wait for the incoming email), so this can be problematic for shopping sites (users are not patient, and they are prone to go shop elsewhere if they find the checkout process too cumbersome). Also, there must be some guardrails to avoid this registration system to be abused into a spamming machine.


I think it can be said that, for Facebook maintainers, making the registration process as smooth and quick as possible is more important than the user's privacy. Really, who would that surprise ?

B T
  • 197
  • 1
  • 9
Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • 8
    +1 insightful commentary about the changing threat environments over time. In Computer Security, as everywhere else, it's too easy to prepare to fight the last war. – gowenfawr Aug 15 '13 at 19:20
  • 14
    I think you're making at least 1 wrong assumption here. You say "Obtaining one account is thus no longer an attacker's goal. Instead, the attacker will want to access specific accounts, with known identities." This simply isn't true. Random accounts can still be valuable to attackers for a variety of reasons. eg. if the account carries a cash balance of some kind that can be stolen, if the account can be held for ransom from it's owner, if there is valuable data or source code in the account. I could go on... – Asaph Oct 29 '13 at 20:40
  • I'm confused on your point at "protecting" the user Email. You say the user expects process to work, and the only point of failure would be an already taken email. So the solution is to send an email explaining that to that email address and "No clue is written on the response Web page". So now this registration is unsuccessful, with no error message returned about why it was unsuccessful, wouldn't that cue the attacker just as much as the error message? Or am I misunderstanding something? – DasBeasto Sep 01 '15 at 19:48
  • 3
    @Asaph I agree. An attacker doesn't just hack a random account merely to gain normal user level access to a system. That's silly. Providing free sign-up doesn't make any such attacks useless to an attacker by any means. – Jordan Melo Apr 27 '16 at 20:22
  • 2
    @DasBeasto On the privacy-sensitive webpage where its registration involves email verification would be: no “failure” message on a failure (“already exists”), **no “success” message on a success**, but only an “email sent” message. You're missing “no `success` message on a success” part. – Константин Ван Nov 15 '18 at 11:12
49

There might be PII risks involved to consider. It is safe to assume that 'everyone' has a Facebook account, therefore disclosing that any one particular email has registered is not a big deal.

But, take another service, like 'depression-help.com' or 'it-burns-when-I-tinkle.net'. It would be a problem to release to the general public that a particular person/email is registered with the site.

Also, for small services with an intentionally small userbase, disclosing usernames can provide additional info to an attacker that could compromise accounts just like that certain 1983 movie.

Hat-tip to @ThomasPornin, but I believe there are some cases, like these that I have suggested, that make it worthwhile to make an informed decision about not disclosing user account names/emails.

schroeder
  • 123,438
  • 55
  • 284
  • 319
  • 5
    +1 Agree. Ultimately it depends on your site. If it's a site where having an account cannot be embarrassing then the risk is minimal. If you run a political site or a porn site, you don't want someone buying a list of 10,000 email addresses and checking against site and knowing who has an account then the privacy and reputation (of your users) risks are very high. – u2702 Aug 16 '13 at 16:01
  • 4
    Let's say I ask a work collegue for his facebook account. He tells me that he doesn't have a facebook account. In fact he has a private account. If I do have his private email address I can prove that he lies to me. – Christian Dec 21 '13 at 20:46
9

There really isn't a graceful way to solve this problem that can make everyone 100% happy. If you force the use of email addresses as usernames, you make it easy to determine whether somebody who has a given email address is a user (privacy problem). If you allow arbitrary usernames, you really can't get around eventually revealing whether or not a given username is already in use, and all you can really do is take steps to slow down a user who's trying to discover valid usernames.

New user registrations are the toughest problem to deal with, because there's no getting around the fact that eventually, you're going to have to gracefully deal with a username collision. Here's one possible option: Have the user enter an email address, a proposed username, and the desired password. Upon submit, validate that the password is acceptable, and email the user a validation URL.

  • If the email address is already in use, but associated with a different username, email that user, remind him that he already has an account, and ask whether he'd like to reset the password.

  • If the email address isn't already in use, but the username is, email the user an error message letting him know that he needs to pick a different username, and has to wait an increasing amount of time between each attempt.

  • If the email address and username are both new, email the user a confirmation link that requires re-authenticating with the new username and password before making it official.

  • DO NOT allow two users to have the same username on the assumption that you can identify one or the other based upon their passwords. Among other things, if two users can share the same username, that means you can never lock out the username due to failed login attempts without affecting BOTH users. And god forbid, if they ever DO happen to somehow pick the same password someday, all hell will break loose.

  • Don't use the same value for username and public identity. You don't necessarily have to actively prevent users from entering the same value for both if they really WANT to, but the default should be to allow users (on something like a message forum, for instance) to have a public nickname that doesn't necessarily have anything to do with the username they log in with.

  • Don't sequentially assign user IDs. Use at least 31, preferably 62, bit random values that are generated and verified as unique at registration time. The nice thing about 31 and 62 bit values is the fact that they neatly translate into 6 and 12-character base36 strings. When debugging, it's a lot easier to remember a 6 or 12-character string of lowercase letters and digits than a 6-17 digit decimal value. The hardest part is responding to requests that specify an invalid user ID with responses that are fake, but can't be readily distinguished from real user ID responses by algorithmic means.

Remember: you can not, and will not, ever succeed 100% at stopping an attacker from occasionally verifying whether or not a given user ID or username is valid. Your goal is to make it as slow and expensive as possible, without unreasonably burdening your real users. For a real-world analogue, think about DVD and Blu-Ray region codes. Back when a player cost $500+, region codes were an effective way to stop almost everybody from playing movies purchased from another region. Now that you can buy a Blu-Ray player for $80, and a HDMI selector for $20 and get change back, there's really nothing to stop a film buff from just buying two or three Blu-Ray players (one per desired region), stacking them up, and running them through the HDMI switch.

For routine logins, be purposefully vague about the reason why THIS login attempt failed, but be equally up-front about the possible reasons... and give them concrete contact information of somebody who can assist them. Keep track of failed logins, and lock out the account if too many failed login attempts are made.

  • Don't tell them outright that the account has just gotten locked out, or is currently locked out... but don't be shy about mentioning it as one of several possible reasons why a login attempt might have failed. Keeping the fact that an account MIGHT be locked out from a user attempting to log in will do nothing to help your security.

  • You don't necessarily have to lock out an account semi-permanently due to failed login attempts. In many cases, you probably shouldn't, because THEN you'll have created a handy denial of service attack. If an account has too many unsuccessful login attempts, you COULD do a "soft" lockout for 1, 6, or 24 hours, at which point the lock will remove itself. This is the one scenario IMHO where it's legitimate to tell a user to "try again later".

An example error message that might be displayed when a login attempt fails:

The username and/or password you entered was not accepted. You might have entered an invalid username, used an incorrect password, or attempted to log in with an account that has been locked out due to excessive failed login attempts. If the account has been locked out, you can contact ___ for assistance[, or wait _ hours for the account to unlock on its own]. Please note that this error message will be the same for all failed logins, regardless of reason.

DO NOT tell them "Something went wrong, please try again later" unless the problem will literally fix itself on its own. It won't fool an attacker, and will seriously annoy legitimate users. This is one of my ultimate pet peeves, and near the top of my list of "horrible things developers do in the name of security theater". Aside from being incredibly annoying, if somebody's account has been compromised, the LAST thing you want them to do is wait until later before bringing it to somebody's attention.

Bitbang3r
  • 321
  • 1
  • 5
4

It's standard facebook behavior that you can seek a account if you have the corresponding email address. These days plenty of people have deactivated that option but that's still the place facebook is coming form.

When doing forum moderation I frequently used that feature to gather information about whether a newly registered account is a registered account of a banned user.

Websites giving away whether email addresses or usernames are real is a way to attack anonymity. I remember a case where someone reregistered who was using the IP of a TOR exit node. I was able to tell the person the name of his mother through information that he shared on facebook. The way to the information went through four hoops of nicknames that were associated to each other.

Disclosure of information like this makes it easier for companies like http://www.spokeo.com/ to operate.

When it comes to protecting privacy you should also consider all data sensitive. Take a forum with 1000 users. Users post harmless information under an nickname. A user logged into the forum with an email address that's associated with his real identity.

With 1000 users there a good chance that I can identify with stylometry and disclosed information which of the 1000 users is the person I'm searching. If I succeed in that task I got a secret nickname.

I can now run google searches on that nickname and also search for nickname@gmail.com in other databases. I also got a larger text sample to make it easier to run future stylometry attacks.

A government level attacker that wants to find dissidents has the resources to query a lot of webservices to check whether certain email addresses exist can also invest into good stylometry systems.

If you want to protect privacy then it makes sense to hide email addresses that are registered.

Christian
  • 1,876
  • 1
  • 14
  • 23