V8-archive: Pw reset token won't invalidate

Created on 12 Dec 2019  Â·  5Comments  Â·  Source: directus/v8-archive

Bug Report

Pw reset token can be used to change pw multiple times without expiring.

Steps to Reproduce

  1. Go to admin login
  2. Click on 'Forgot password'
  3. Click pw reset url of the email received
  4. Enter new password and submit
  5. Reload page
  6. Enter another password and submit

Expected Behavior

Error message saying pw reset token is expired

Actual Behavior

Pw gets changed again

Other Context & Screenshots

There's a TODO comment in line 478 of api/src/core/Directus/Authentication/Provider.php – so it's not implemented correctly yet?

Technical Details

  • Device: Desktop, iPhone 8
  • OS: MacOs 10.15.2, iOS 13.2
  • Web Server: Apache
  • PHP Version: 7.3
  • Database: MySQL 8.x
  • Install Method: cloned master branch
bug

All 5 comments

@benhaynes @rijkvanzanten - Current flow of forgot password;

  • Click on the Forgot Password
  • A link which contains the JWT Token will be generated.
  • JWT token will be expired based on the expiration time - we don't have any specific method to invalidate the JWT token.

So, until the expiration time will not increase from the current time - the user can update their password.

To restrict this; we should add one table directus_password_reset with the below fields.

  • user_id
  • token [Instead of JWT token we should use some random n number user-specific string]
  • use_at [Time where the user reset the password]

Instead of adding the use_at field; we can remove the entry from the table too.

Let me know your thoughts. :)

To restrict this; we should add one table directus_password_reset with the below fields.

I don't agree. I'd rather not add a whole new directus_ table for just password reset tokens.

Instead, we should consider having a password reset token column in directus_users that can be set, referenced, and removed when password has been reset, _or_ add a "password_last_updated_at" datettime value in the directus_users table that we can use to verify the password reset token (if token creation date < password_last_updated date, it's already been used).

I agree with the simplicity of what Rijk proposed. The only downside (which I don't mind), is that if you request a password reset 3 times, the first 2 will be invalid and only the latest will work. But this is also a good security feature so that random unused reset tokens are n't floating around.

if token creation date < password_last_updated date, it's already been used

Hey @rijkvanzanten - I'm sorry but maybe you are missing one point. What if user tries to reset the password again after resetting it once before the expiration time?

Let's assume; user tried to reset the password at 14:00:00 16-12-2019.
token_expiration for the generated token is 15:00:00 16-12-2019 and user reset it immediately so DB will have 14:05:00 16-12-2019 as password_last_updated_at.

So the user will able to reset the password using the same token from 14:05:00 16-12-2019 to 15:00:00 16-12-2019 - which is wrong.

That's why I was recommended to add a table for this flow as when the user tried to reset the password the table will contain the token as well as used_at timestamp. So when they tried to use the sametoken we can return the error.

Kindly provide your inputs for this point too :)

That's why I said check the token _creation_ date, not the expiration date. Also, the other option of adding a single token column is simpler and more foolproof, so I'm voting to use that

Was this page helpful?
0 / 5 - 0 ratings

Related issues

binary-koan picture binary-koan  Â·  3Comments

cdwmhcc picture cdwmhcc  Â·  3Comments

ondronix picture ondronix  Â·  3Comments

gitlabisbetterthangithub picture gitlabisbetterthangithub  Â·  3Comments

HashemKhalifa picture HashemKhalifa  Â·  3Comments