Email enumeration through login and forgot password functionality - google-oauth

The login and forgotten password functions can be used to enumerate valid email addresses on the application, as they return different messages depending on whether or not the emails are registered. Is there a way to avoid this?
This question was asked before: Google Identity Toolkit v3 Email enumeration through reset password functionality but remains unanswered so posting here with the google-oauth tag to see whether it reaches the right people.

Related

Signed up and hit remember me- Avoid asking user which account from list in Google OAuth and instead auto sign in to the specific remembered email

I set up an account creation page with a remember me and a jwt token verification via WorkOS. There is no password creation and just this verification (plan to add in password later if needed as the country uses OTP more than passwords)
A new user creates an account and selects remember me (using JavaScript).
The next time I sign in, I have my account populated like a*****#gmail.com.
A lot of websites I have seen have it so that when you click on this email, it goes to the full list of all gmails and you have to select that email again.
I’ve seen this remember me automatically sign in only if the user saves a password (like Facebook - see other profile accounts in sign in and you click and go in directly). But above mentioned this country doesn’t prefer passwords as much as OTP. I don’t have a password yet and really looking to avoid adding it in unless it is absolutely necessary to do this.
My goal: I don’t want to see this full screen of all gmail accounts in Google OAuth also referred to in documentation as the Account picker. I just want it to automatically sign in to the specific remembered account selected, assuming I have that gmail password saved.if the user doesn’t have the gmail password saved then, they will be directed to that specific emails sign in screen
How do I bypass this full list of gmail accounts and manual selection and just automatically sign in to my remembered email account?
I’ve looked at older answers on here but nothing seems to fully handle this. I’m wondering if this will help me achieve this.
https://developers.google.com/identity/gsi/web/guides/automatic-sign-in-sign-out
I’ve tried just having the email remembered and then they click on it and it asks do you want to sign in via gmail or magic link? That works and is better than not providing the remember me at all, but it’s only half way.

Does forgot password routine mean passwords are not necessary?

For some less critical websites it seems common for a user to be able to reset their password if they have forgotten it. The fact that they can access the email account that they registered with is considered good enough.
In those cases the only advantage of the password seems to be that, if the user can remember it, they don't have to check their emails in order to access the website.
Although not having to check your email is a convenience it has to be weighed against the inconvenience of remembering a large number of passwords for all the websites that require them.
A user would register their email address and verify it by responding to a link sent to their email address. After that, every time they wanted to access the site they would enter their email address into the login form and then click the link in the email sent to them.
Is there an argument for less critical websites to allow access without a password in this way?

Best password reset behavior for missing account

I'm wondering what the best behavior is when a user requests a password reset for an email that doesn't exist.
Context: user is not logged in. They just enter an email and hit a reset button.
If I tell the user requesting the reset immediately that the account doesn't exist, that's both a bit of security hole and a privacy issue.
If I do nothing and it's an innocent mistake (they thought they had an account), they'll be wondering what the heck happened. Most mysterious option, least subject to abuse.
I can send an email that says a password reset has been requested but there's no account (and should be ignored blah blah blah). This seems the least noxious but it is a little subject to abuse.
Update: On further consideration, I don't really so how 1 is a big deal since they can get the same information by simply trying to sign up/use the same email ... unless I'm missing something ...
I personally would go this way:
User enters e-mail address.
Screen says "request will be processed, e-mail has been send" or something along those lines.
If there is no account linked with this e-mail address: don't send a mail, but don't tell the guy requesting.
If there is an account linked with this e-mail: send the reset e-mail including the usual "if this wasn't you simply ignore this mail, if you suspect abuse please contact $foobar"-message.
Here is why i would NOT tell anyone whether an account is linked with this e-mail address: Privacy. If you told everyone, everyone could check if $person is using $service.
Figured i would include why i wouldn't send a mail if there was no such user: Why should i? The user will probably either know which email address he used or try several at once (or only wait a short time span). Of course there are cases in which it would be a bit more userfriendly if one would send those mails, but they aren't important enough to negate the abuse potential.
There is not much abuse potential if only one website does that stuff (as long as they wouldn't send multiple mails in a short timespan), but imagine every webservice going this way. You would just have to collect a few of those services and then emailbomb someone 'you' dislike, without hitting any spamfilter!
Personally, i'm a fan of:
The user enters an email.
Whether or not the email exists, say that it has been requested, and if you do not receive an email shortly, try again or contact us.
In the email, state a password request was submitted, and if it wasn't the user, then to ignore the email.
Also,
If you're worried about bots scraping your site for emails, add a Captcha.
If you're worried about people hacking accounts, add a second layer that prompts for a secret question answer.
In my opinion the third option is the best compromise between user-friendlyness and security. Option 1 seems to be to big of a privacy issue. Using option 2 the user can not know if he has an account, but registered with another email address or if the reset system doesn't work.
I would do something like this
Ask for the username or email
If that email or username is present, send all the email to the person, with the reset password.
Finished :)

How much user data should be required to grant a password reset?

I'm looking to add password-reset functionality to my site and have been browsing the numerous threads discussing various aspects of that issue here on SO. One thing I haven't really seen clarified is how much information to require from the user for confirmation before sending out the reset email.
is email alone enough?
email + account username?
email + account username + some other identifying value all accounts must input?
I don't want my site to seem like an old wrinkly nun with a ruler, but I don't want people to be able to abuse the password reset system willy-nilly.
Suggestions?
I use just an email and send an email to that person with an activation code in a link. That activation code expires within 2 days and once it gets uses it also is invalidated.
This means the person has to have access to that email account in order for it to work, and it can only be used once.
It is not uncommon to use the email + account username, but my email IS what you sign in with, there are no usernames. The decision is up to you.
I think email is enough without it becoming a nuisance.
First concern should be security. How bad would it if another person got a hold of a user's password? If this is unacceptable, I'd say what Babiker said - email and a security question of some sort, preferably something that's never communicated between the site and the user, with the exception of sign-up process or a security settings edit by the user. The assumption here is that the user's email account has been compromised.
If security is not a huge deal, i.e. there are no real privacy/financial/etc risks involved, I think email is enough. To minimize risk for nuisance, you could do what Kerry suggested - i.e. not reset the password automatically, but provide a verification link. Also, you might want to place some restrictions on how frequently the feature can be used by a given user to prevent someone from filling your inbox by repeatedly entering your email.
Email
Some other identifying value all accounts must input. Like a security question.

Forgot Password: what is the best method of implementing a forgot password function?

I'm wondering what the best method is for creating a forgot password function on a website. I have seen quite a few out there, here are a few or combination of:
passphrase question / answer (1 or more)
send email with new password
on screen give new password
confirmation through email: must click link to get new password
page requiring user to enter a new password
What combination or additional steps would you add to a forgot password function? I'm wondering about how they request the new password and how they end up getting it.
I'm operating on the principal that the password cannot be retrieved; a new password must be given/generated.
Edit I like what Cory said about not displaying if the username exists, but I'm wondering what to display instead. I'm thinking half the problem is that the user forgot which email address they used, which displaying some sort of "does not exist" message is useful. Any solutions?
I personally would send an email with a link to a short term page that lets them set a new password. Make the page name some kind of UID.
If that does not appeal to you, then sending them a new password and forcing them to change it on first access would do as well.
Option 1 is far easier.
A few important security concerns:
A passphrase question / answer actually lowers security since it typically becomes the weakest link in the process. It's often easier to guess someone's answer than it is a password - particularly if questions aren't carefully chosen.
Assuming emails operate as the username in your system (which is generally recommended for a variety of reasons), the response to a password reset request shouldn't indicate whether a valid account was found. It should simply state that a password request email has been sent to the address provided. Why? A response indicating that an email does/doesn't exist allows a hacker to harvest a list of user accounts by submitting multiple password requests (typically via an HTTP proxy like burp suite) and noting whether the email is found. To protect from login harvesting you must assure no login/auth related functions provide any indication of when a valid user's email has been entered on a login/pass reset form.
For more background, checkout the Web Application Hackers Handbook. It's an excellent read on creating secure authentication models.
EDIT: Regarding the question in your edit - I'd suggest:
"A password request email has been
sent to the address you provided. If
an email doesn't arrive shortly,
please check your spam folder. If no
email arrives, then no account exists
with the email you provided."
There's a trade-off being made here between ease of use and security. You have to balance this based on context - is security important enough to you and your users to justify this inconvenience?
Send email with new password.
FORCE a password change when they arrive and key in the new password.
This ensures that the person who wanted the password will be the only only getting in to the account.
If the email is sniffed, someone could get in to the account (of course), but the real party will discover this immediately (as their password you just sent them doesn't work).
Also send confirmations of password changes to the users.
If someone get the new password, and then an email saying "thanx for changing the password", they're going to be rather puzzled and will talk to an admin if they didn't do it.
Using the email verification/password reset link will give you better security.
If you look around this is how most websites do it and people are pretty used to this verification, so I'd recommend using this type of authentication.
I would think (gbrandt's) Option 2 would be a great method if it is combined with some personal information you already have for the user. i.e date of birth.
When the user requests a new password (reset) via entering his email address, he also has to enter a correct date of birth (or something else) before the password is reset and a new one is emailed to the user.
Only those who know him well can possibly annoy him by resetting his password! It cant be a stranger or a bot
Upon 5 or 7 bad email-address & date of birth combinations the user is emailed that his password has been requested to be reset and has failed due to an incorrect credential. Then password resetting for that account is suspended for 24hrs or any desired period.
(if too many users contact the webadmin regarding this email he'll know someone is trying to maliciously attain information from your website/app)
What do you guys think?
Option 1. is not a good idea, as generally his becomes easily guessable by others. Sarah Palin's personal email (Yahoo I think) was hacked in this way by a third party.
The other options are better and previous posts have outlined the detail.
The idea I was thinking about was to sign the data in the link that is sent to the user. Then, when the user clicks the link and the server receives the call, the server also gets the encrypted part and can validate that the data was untouched.
I have implemented a JAVA project for this use case. It is on GitHub, open source. It answers your question perfectly... implemented in Java.
As for the link in the email - it generates the link, plus validates it upon usage.
There are explanation for everything (and if something is missing - let me know...)
Have a look: https://github.com/OhadR/Authentication-Flows
See a Demo here.
This is the client web-app that uses the auth-flows, with the README with all explanations. it directs you the implementation: https://github.com/OhadR/authentication-flows/tree/master/authentication-flows