2

I decided to implement "forgotten password" functionality, without having to create a website just for that. The usual workflow that I've seen for any app is:

  1. User requests password reset
  2. Link is sent to their email with a token embedded in URL
  3. They click the link which redirects them to a website, where they change the password.

I Have implemented it differently and I would like to know if there are any security flaws with this approach:

  1. It's a 2 step process in the mobile app. In the first step, the user requests password reset, they are asked to input their email:

enter image description here

  1. Once email is entered, the API will check if the user exists, and generate a 8 character alphanumeric token (eg. A7DF53X0). It doesn't let the user know whether the account exists, or whether the email has been sent, basically if account exists, email is sent.
  2. Once user clicks Confirm in the first step, they are now being shown a second step screen (no matter if the account exists or not - to make sure we don't flag to anyone that account with that email exists):

enter image description here

  1. The user now must enter the received code and the new password. If the code is correct and password passes validation, they are informed that password has been changed and redirected to the login screen, to log in again with the new password. Note that email from the first step is used in this request, saved in SecureStorage

  2. If the code was incorrect, code is invalidated in the database and they are asked to request a new code. Only 3 codes can be requested for an account in the 24h period to avoid bruteforcing. Each code is also only valid for 5 minutes from the moment they are generated.

  3. If the email in the first step was incorrect (the account doesn't exist) the user will still be prompted to input the code and new password and on confirm they will also receive same message saying that code is incorrect. This is to make sure that potential attackers have no idea whether the email they entered is actually linked to any account or not.

  4. If there already were 3 attempts in the 24h period - email will be sent after the first step, informing the user about it (instead of the new code) but the workflow in the app will not change, making an impression that the process is "as normal" - again to not let out any information to the potential attacker

Are there any obvious flaws (security or other) in this workflow that you can see? Please disregard SSL issues, it will be SSL once live.

Varin
  • 121
  • 3
  • "Once user clicks `Confirm` in the first step, they are now being shown a second step screen (no matter if the account exists or not)." I fail to make any sense of this condition. If the E-Mail did not exist, how would someone receive a valid reset code? – Beltway Nov 29 '21 at 11:14
  • @Beltway They wouldn't. I don't want to let the potential attacker know that an account with that email exists. If there was a message saying "Sorry, account with that email doesn't exist" then this could be used by an automated script using a database of email addresses to check if those email addresses have accounts in my app. If the account with the email exists, the account holder will get the email. If the account doesn't exist, there is no need to let the potential attacker know this as this would narrow down the attack vector. – Varin Nov 29 '21 at 11:23
  • `automated script using a database of email addresses`. That is not feasible, as someone would require huge amounts of valid reset tokens to reasonably automate such an attack. I suggest using 'much' longer reset tokens that are automatically passed through the URL. Chances to brute force tokens are diminished and no chance of users entering invalid passcodes. – Beltway Nov 29 '21 at 11:46
  • @Beltway Even if it's one email it's a security risk. If someone knows your email, and my App is something like "Tinder", would you like it to be possible for anyone who knows your email to know whether you have "Tinder" account? This is why none of the password reset workflows ever tell you whether the account exists or not when you enter the email. They just tell you "If account exists, the email will be sent" Your suggestion about much longer reset tokens passed via URL to the mobile app how? I want to avoid deeplinks to the APP, I want to use code that can be entered manually. – Varin Nov 29 '21 at 11:53
  • 'none of the password reset workflows ever tell you whether the account exists or not when you enter the email'. This corresponds to the reset initiation which is not what I am referring to. There is no need to prompt a user for a reset token immediately after requesting one, the prompt should be initiated through the E-Mail containing the reset token and only be displayed when it is valid. Hiding to which account the valid token belongs has no benefit at this point, as we can safely assume it was issued to the rightful owner. This is common practice as it yields improved usability. – Beltway Nov 29 '21 at 12:06
  • @Beltway How can email initiate a specific mobile app screen asking to enter the code? That would require deep links - that's only possible if your app is in AppStore or Play. If I wanted to use links in emails, I'd just build the website to reset/change the password and go with the normal approach. The whole question is about being able to enter the code in the app that is being sent to the email. – Varin Nov 29 '21 at 12:14
  • 1
    I just found [this resource](https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html#methods) going through some interesting points on PINs and URL tokens, might be worth reading, too. – imsmn Nov 29 '21 at 12:16
  • I should work when including the token as a URI fragment, the prompt will likely have to be displayed in an I-Frame through, – Beltway Nov 29 '21 at 12:16
  • @Beltway - And that would require some sort of website built for the purpose to change the password that would be then displayed in iframe in the app? I specifically don't want to build such a website. Also, I don't quite understand how clicking a link in an email could open my mobile app and go to a specific screen? Not sure if I'm missing something? – Varin Nov 29 '21 at 12:20
  • Deep-linking is possible in both iOS and Android, I don't know about a common Xamarin API. It should also work without I-frames if you wrap the reset token exchange in a POST but I suspect the former to be less verbose implementation wise. – Beltway Nov 29 '21 at 12:25
  • On second thought; since Xamarin is soon legacy and to replaced with MAUI you can include I-Frames through the common API with Blazor bindings. – Beltway Nov 29 '21 at 12:26
  • @Beltway I-frame solutions will require companion website either way. Deep links work best if the app is in Play Store or App Store. Deep linking works in iOS/Android above certain versions. Deep links in emails will also need companion website as they won't be clickable. Deep linking won't work if user doesn't have email app on the phone but opens them on their PC. The PIN-to-email idea is same as PIN-via-text-message idea. The prompting user for a pin/code straight after requesting it is a tradeoff in order to not use deeplinks or companion website. For genuine user - it won't really matter. – Varin Nov 29 '21 at 12:56

0 Answers0