Skip to content

Commit

Permalink
BACKPORT Invalidate password reset links on password change (indico#5878
Browse files Browse the repository at this point in the history
)
  • Loading branch information
ThiefMaster authored and SegiNyn committed Aug 2, 2023
1 parent d569882 commit b707074
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
36 changes: 36 additions & 0 deletions CHANGES.rst
Expand Up @@ -4,6 +4,42 @@ Changelog

Version 3.1.1
Version 3.2.7
Version 3.3
-----------

*Unreleased*

Major Features
^^^^^^^^^^^^^^

- Nothing so far

Internationalization
^^^^^^^^^^^^^^^^^^^^

- Nothing so far

Improvements
^^^^^^^^^^^^

- Invalidate password reset links once the password has been changed (:pr:`5878`)

Bugfixes
^^^^^^^^

- Nothing so far

Internal Changes
^^^^^^^^^^^^^^^^

- Use (dart-)sass instead of the deprecated node-sass/libsass for CSS compilation
(:pr:`5734`)


----


Version 3.2.8
-------------

*Unreleased*
Expand Down
10 changes: 7 additions & 3 deletions indico/modules/auth/controllers.py
Expand Up @@ -28,6 +28,7 @@
from indico.modules.users.controllers import RHUserBase
from indico.util.i18n import _
from indico.util.signing import secure_serializer
from indico.util.string import crc32
from indico.web.args import use_kwargs
from indico.web.flask.templating import get_template_module
from indico.web.flask.util import url_for
Expand Down Expand Up @@ -573,10 +574,12 @@ def _process_args(self):

def _process(self):
if 'token' in request.args:
identity_id = secure_serializer.loads(request.args['token'], max_age=3600, salt='reset-password')
identity = Identity.get(identity_id)
data = secure_serializer.loads(request.args['token'], max_age=3600, salt='reset-password')
identity = Identity.get(data['id'])
if not identity:
raise BadData('Identity does not exist')
elif crc32(identity.password_hash) != data['hash']:
raise BadData('Password already changed')
return self._reset_password(identity)
else:
return self._request_token()
Expand All @@ -592,7 +595,8 @@ def _request_token(self):
# secure as we'd expose valid usernames for a specific user to an untrusted person.
identity = next(iter(user.local_identities))
_send_confirmation(form.email.data, 'reset-password', '.resetpass', 'auth/emails/reset_password.txt',
{'user': user, 'username': identity.identifier}, data=identity.id)
{'user': user, 'username': identity.identifier},
data={'id': identity.id, 'hash': crc32(identity.password_hash)})
session['resetpass_email_sent'] = True
logger.info('Password reset requested for user %s', user)
return redirect(url_for('.resetpass'))
Expand Down

0 comments on commit b707074

Please sign in to comment.