Create Auth0 user - auth0

I'm using Management API V2 to create users and I'm setting their password in the creation process.
After that they're receiving an invitation email to confirm their email address because I'm setting the parameter "verify_email" to true.
What I need to do is:
Create User
Send the user an invitation email so they can confirm their email
address.
Giving them the option to set their own password, instead of me
setting it in the creation process "step 1"
I looked up in the community before asking, and I found that I can trigger password reset flow upon the creation, is there any different way to do it? because this doesn't look like the correct way to do it, there should be a way to do so.
Thanks

Triggering reset password email is the right approach. You can use authentication API to send the reset password email.
https://auth0.com/docs/api/authentication#change-password
More options are described here: https://auth0.com/docs/connections/database/password-change

Related

Passwordless Authentication with Cognito - How to determine if a user signed up with email or phone number

We have implemented the Custom Auth Triggers as described link here. We have the user pool set up to let users log in with either phone number or email.
The provided case is - the user has email & phone both verified in their Cognito account
The problem I am having is determining what medium (email or phone number) the user signed in
When observing the event passed into the define / create/verify auth triggers, it seems like doesn't pass through what the username was used to initiate the authentication flow.. only the user attributes which in my case there could be both email or phone. I need to know which one it is so I know if I need to send the code through SMS or Email.
I also read about ClientMetadata this key we can pass from in InitiateAuthCommandInput but it will provide a client metadata key only below these triggers
Pre signup
Pre-authentication
User migration
but it will not provide ClientMetadata in these triggers
Post authentication
Custom message
Pre token generation
Create auth challenge
Define auth challenge
Verify auth challenge
After googling it too much, I found an article which had a tricky solution:
here is the link
I am not able to implement the provided solution.
I found a similar question in stack overflow too Link but there is also no answer, Can anyone please help me with this.
This is a workaround by adding a custom attribute during passwordless login
Actually, the authenticationUser function needs to identify whether the user is adding email or phone during login
Step 1: during login process, before calling initiateAuthCommand, First set a custom attribute in Cognito user object - logged_in_by - email or phone
Step 2: once you add a key after that InitiateAuthCommand will be started and call the triggers
Step 3:
When createAuthChallenge runs at the time we will have userAttributes.logged_in_by.
If this attribute contains email this indicates that the user is trying to login with the email and we need to send OTP over email.
If this attribute contains phone this indicates that the user is trying to log in with the phone and we need to send OTP over the phone number.

Send password to new user

I would like to ask some questions about password security. In my software the admin can create a new user setting the password and the username. I believe sending the password in plain text in an email is not a very good idea, so I’m thinking about sending a link that redirect the user to a page where they can set up their password. This link should expire after few hours as well. On my login form I’ve also have the option “forgot password” how can I prevent that a user doesn’t use it until they create the new password? How would you do it?
A password reset link is technically exactly the same as a registration link, both are relying on the "fact" that only the owner of the email address can read the link. So there is no reason to prevent a password reset when the user did not yet login.
The usual workflow is slightly different though, usually the user makes the first contact with the site and on the register page (s)he is asked to enter a password.

user log in while forgot password process begun, let im in?

I'm in the middle of implementing "forgot password". my auth is via jwt access token. (user log in, gets an access token, sends it with the rest api calls).
so let's say the user which currently isn't logged in, click the "forgot password".
i create for him some hashed token, and then send him a mail.
if he will click it I'll decode, display him the change password, and create a new access token, like this is the main idea and all good.
My question is for this scenario:
user clicks forgot password, enter his mail, i send him a mail, but then instead of clicking the url and resetting, he logs in via his password.
should i let him log in? creating an access token and all good? while resetting the token from the sent mail (or is it still a valid token to reset the password with?)
display some error saying go to your mail and continue forgot password process?
my question is from security aspects, since maybe a user think his password was compromised, and then if i do let him in, then maybe someone who got the password (which isn't the user) can still log in /change password - while the original user goes to the mail and think he processed with the process.
i know it's maybe a rare race condition but i would like to avoid it.
(also, if i do let him in, and then he click the url from the mail which was already sent, should i reset it? in my scenario, maybe it's better not to reset? or if a user click twice "forgot password" should i create 2 different tokens, accepting only the later?)
ii realy would appreciate an advice, how to handle that scenarios, all forgot password related.
thanks.
Im not an Expert. This is just my opinion:
The "Forgot Password" funktionality should not render the old password unusable as someone else could invoke this process to prevent the owner of the acount from logging in.
It could take you quite some time to realize the email and would cause a lot of headdache.
When someone requests multiple emails in a short while they should all be functional. It happens often that the mail servers take their time and humans are not known for their patience so they click the button twice but use the first link arriving in their inbox.
This is all conserning usabilty.
Now to security:
The emails should also stay active when someone loggs in. As you mentioned a malicious actor could log in and otherwies prevent the owner from changing their password that way.

"Forgot username" flow for AWS Cognito?

I'm using ASW Cognito for authenticating users. Cognito has a well-documented flow to handle users who have forgotten their passwords.
How do I handle users who have forgotten their usernames? Is there a built-in flow that lets the user enter their email or phone number, and then receive an email or text with their associated username? I found the ListUser API, which returns all the users in a userpool. I could write a Lambda function that filters through all my users, looking for a match on email or phone number. But this seems like overkill.
Unfortunately, there is no default out of the box workflow of "Forgot Username".
I am implementing similar workflow. We ask user for their registered phone number/email, and we retrieve username based on that number and send it to email/phone according to configuration. If user is configured to use email and phone both, we send SMS to phone if user forget username (which is email id they used during sign up).
One major drawback of this approach is that, we need to provide ListUsers API call access to anonymous user which is a potential security issue but can't seem to find any other way by which we inform user about their login details.
For those, who are looking for the solution, don't give the anonymous user access to ListUser API as suggested in the accepted answer.
There are two ways to implement 'Forgot username flow'.
Enable email as an alias for your Cognito User Pool:
Calling this API causes a message to be sent to the end user with a
confirmation code that is required to change the user's password. For
the Username parameter, you can use the username or user alias. The
method used to send the confirmation code is sent according to the
specified AccountRecoverySetting.
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ForgotPassword.html
The user will be able to reset the password with their email and code delivered to provided email address. If you still want to remind the username, you can use Lambda trigger to generate the password reset email with both username and verification code.
Use the backend (web server or lambda) which will receive the email address as an input to the 'Forgot username flow'. The backend will have permissions to invoke List Users API (https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListUsers.html) and will perform user lookup using the email. You now can go into Forgot Password flow using the retrieved username. Lambda trigger will be used to generate password reset email with username and verification code.
You can protect this API from abuse using WAF and/or captcha.

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