Have inherited an auth0 sign up flow that needs attention for a new client facing application. Users are created internally and sent to Auth0 via the API.
Our full flow looks like so:
- A User is created in internal system with an Id, email and phone number
- This user is created in Auth0 via the IManagamentAPIClient c# like so
managementApi.Users.CreateAsync(clientRequest);
It is created with a default password…. ( not user set )
- Once the user is created we then use the IAuthenciationApiClient to send a password reset email like so… This acts as the entry point into our system in the absense of a Register or Welcome email since the user is created in step 2.
await authenticationApi.ChangePasswordAsync(new() { Connection = auth0Settings.Value.Connection, Email = user.Email });
- The change password ( Link ) email template is used here and we change the wording to make it look somewhat a welcome email ( using some metadata properties set )
- This email link has an expiry of a few days meaning if a user clicks on this link in the email after 2 days they are presented with a ‘Expired Link’ dialog.
- THE ISSUE is that at this point the user is able to navigate to the normal login screen and select ‘Forgot Password’ and essentially sign up without going through the email link at all. This basically means the expired link in the email is completely pointless and giving us no layer of security other than a dialog saying its expired.
So, a few questions…
How might we tweak our flow so that an expired ‘Sign up’ or ‘Register’ link completely blocks a user from logging in?
Are we creating an anti-pattern creating the users upfront and then sending them a reset password email as the initial email?
Happy to give more information if required but this is as concise I can be as of now.
as a matter of fact it seems we actually follow this guide from Auth0 Implement User Invitations for Application Sign-Up using Password Reset Emails - Auth0 Docs so i’d be interested if others have done the same and how they have solded my concerns
Hi @jharrison
Welcome to the Auth0 Community!
Indeed, the scenario you have presented considered an anti-pattern and if not handled, this indeed would indicate a security flaw allowing users to bypass the invitation system of your application.
My suggestion in order to prevent the users from resetting the password by themselves would be to deny access to users using a password-reset-post-challenge trigger whenever email_verified is false. Since you are creating the users, this should be by default false. The code for this would look like this:
exports.onExecutePostChallenge = async (event, api) => {
if(event.user.email_verified === false)
{
//Deny access to the user
api.access.deny("Please reset your password through the invitation link");
//Redirect to a custom error page informing the user
api.redirect.sendUserTo("https://my-app.exampleco.com/password_reset_denied");
}
};
This is where the tricky part comes:
- Instead of sending a password change email to the users, you will need to send a email verification email to your users
- Create a password change ticket for the respective user
- Inside the verification email, you will need to attach an email verification ticket which has the
result_url parameter the password change ticket generated beforehand
This way, the users will be blocked to change the password via Universal Login if their account has not been verified and will be forced to reset it through the activation email you will be generating for them.
It can be quite an extended workaround, however, the initial flow you have described would be expected in order to avoid redundancy. Basically, an user who is able to change the password via an email automatically sent to them by the app should be able to ask for a password change email themselves via the Universal Login UI.
Hope the information above is helpful regarding the matter, if you have any other questions, let me know!
Kind Regards,
Nik