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:
- User requests password reset
- Link is sent to their email with a token embedded in URL
- 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:
- 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:
- 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.
- 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):
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 inSecureStorage
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.
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.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.