I tried submitting this to stack overflow and looking it up on google. I'm just looking for a standard safe way to reset passwords. I came up with this and wondered if it would be ok to use. Is there anything wrong with this procedure? 1. Enter in username and email in a reset form. 2. Flask creates a really long random string and stores it into the session under "reset_code". Session will also have a key for "reset_pw_username" 3. Flask sends an email with a link to the path /password_reset/reset_pw_username/reset_code 4. That link displays a form where the customer can reset the password if the session reset code matches the session reset_code item. Otherwise it bombs out. 5. The session will expire the reset code after an hour. Am I missing anything? -Matt
On 10/12/11 15:57, Matthew Karas wrote: > I'm just looking for a standard safe way to reset passwords. I use `itsdangerous` library for this kind of things. http://packages.python.org/itsdangerous/ A token formed by the user name and an expiry time is signed with a secret and a salt (specific for the password reset operation). This token is sent to the user, in the form of an URL: http://localhost/profile/<username>/preset?token=<token> In the preset view I verify the token (given that the token encodes the username, you can even leave it out of the URL). This way you do not have to store anything server side or in the session, making it a very lean solution. Cheers, -- Daniele
Hi Matt, sounds good, but if i remember correctly the default sessions are cookie-based, which means that the signed cookie cannot be modified, but can be read. So using a cookie-based session would make it possible to reset every password without having access to the emails! Maybe you can store a hash of the reset_code instead, and just verify the reset_code against the hash? I've not implemented this in Flask myself yet, but with Django I have always used django-registration for password resets. Maybe it can help: https://bitbucket.org/ubernostrum/django-registration/src/fad7080fe769/registration/models.py#cl-62 Best Regards, Jesaja Everling On Sat, Dec 10, 2011 at 3:57 PM, Matthew Karas <matthew.james.karas@gmail.com> wrote: > I tried submitting this to stack overflow and looking it up on google. > > I'm just looking for a standard safe way to reset passwords. I came up with > this and wondered if it would be ok to use. > > Is there anything wrong with this procedure? > > Enter in username and email in a reset form. > Flask creates a really long random string and stores it into the session > under "reset_code". Session will also have a key for "reset_pw_username" > Flask sends an email with a link to the path > /password_reset/reset_pw_username/reset_code > That link displays a form where the customer can reset the password if the > session reset code matches the session reset_code item. Otherwise it bombs > out. > The session will expire the reset code after an hour. > > Am I missing anything? > > -Matt
That sounds like a great idea - that's why I ask. So I would add an pwreset_hash and pwreset_hash_created column to my usertable and send the un-hashed key to the users email. I would then check to see if the hash is expired (1 day old) - then compare the hashed key to the stored hash. Thanks, Matt On Sat, Dec 10, 2011 at 10:38 AM, Jesaja Everling <jeverling@gmail.com>wrote: > Hi Matt, > > sounds good, but if i remember correctly the default sessions are > cookie-based, which means that the signed cookie cannot be modified, > but can be read. > So using a cookie-based session would make it possible to reset every > password without having access to the emails! > Maybe you can store a hash of the reset_code instead, and just verify > the reset_code against the hash? > > I've not implemented this in Flask myself yet, but with Django I have > always used django-registration for password resets. > Maybe it can help: > > https://bitbucket.org/ubernostrum/django-registration/src/fad7080fe769/registration/models.py#cl-62 > > Best Regards, > > Jesaja Everling > > > On Sat, Dec 10, 2011 at 3:57 PM, Matthew Karas > <matthew.james.karas@gmail.com> wrote: > > I tried submitting this to stack overflow and looking it up on google. > > > > I'm just looking for a standard safe way to reset passwords. I came up > with > > this and wondered if it would be ok to use. > > > > Is there anything wrong with this procedure? > > > > Enter in username and email in a reset form. > > Flask creates a really long random string and stores it into the session > > under "reset_code". Session will also have a key for "reset_pw_username" > > Flask sends an email with a link to the path > > /password_reset/reset_pw_username/reset_code > > That link displays a form where the customer can reset the password if > the > > session reset code matches the session reset_code item. Otherwise it > bombs > > out. > > The session will expire the reset code after an hour. > > > > Am I missing anything? > > > > -Matt >
If you store the reset code in your database, and not in a cookie-based session, then it shouldn't be problematic to store it unencrypted. Using a hash anyway doesn't hurt, I would use bcrypt for this. http://pypi.python.org/pypi/py-bcrypt/ Best Regards, Jesaja Everling On Sat, Dec 10, 2011 at 5:06 PM, Matthew Karas <matthew.james.karas@gmail.com> wrote: > That sounds like a great idea - that's why I ask. > > So I would add an pwreset_hash and pwreset_hash_created column to my > usertable and send the un-hashed key to the users email. I would then check > to see if the hash is expired (1 day old) - then compare the hashed key to > the stored hash. > > Thanks, > Matt > > > On Sat, Dec 10, 2011 at 10:38 AM, Jesaja Everling <jeverling@gmail.com> > wrote: >> >> Hi Matt, >> >> sounds good, but if i remember correctly the default sessions are >> cookie-based, which means that the signed cookie cannot be modified, >> but can be read. >> So using a cookie-based session would make it possible to reset every >> password without having access to the emails! >> Maybe you can store a hash of the reset_code instead, and just verify >> the reset_code against the hash? >> >> I've not implemented this in Flask myself yet, but with Django I have >> always used django-registration for password resets. >> Maybe it can help: >> >> https://bitbucket.org/ubernostrum/django-registration/src/fad7080fe769/registration/models.py#cl-62 >> >> Best Regards, >> >> Jesaja Everling >> >> >> On Sat, Dec 10, 2011 at 3:57 PM, Matthew Karas >> <matthew.james.karas@gmail.com> wrote: >> > I tried submitting this to stack overflow and looking it up on google. >> > >> > I'm just looking for a standard safe way to reset passwords. I came up >> > with >> > this and wondered if it would be ok to use. >> > >> > Is there anything wrong with this procedure? >> > >> > Enter in username and email in a reset form. >> > Flask creates a really long random string and stores it into the session >> > under "reset_code". Session will also have a key for "reset_pw_username" >> > Flask sends an email with a link to the path >> > /password_reset/reset_pw_username/reset_code >> > That link displays a form where the customer can reset the password if >> > the >> > session reset code matches the session reset_code item. Otherwise it >> > bombs >> > out. >> > The session will expire the reset code after an hour. >> > >> > Am I missing anything? >> > >> > -Matt > >