The context is a password reset functionality. The user has requested a password reset, either via the web, or via a call to the help desk.
The proposed solution is, behind the scenes:
- If Self-Service via the web - require the user to prove that they are the account owner by making them answer their security question
- Set the password to a temporary, randomly generated password
- On the server, generate an email that contains a link
- The user clicks the link and is prompted to enter a new password
- As long as the new password meets complexity requirements, the new password is set.
The question is, there are two options on the table for the link that is sent to the user.
Option 1: a lookup table of random tokens mapped to usernames, with an expiration.
Option 2: Encapsulate the username, temporary password, and expiration time into an encrypted blob, and send that in the email, and avoid the database
I'm concerned that option 2 is less secure. The data may be logged or cached in proxy servers. And even though the blob is encrypted, the fact that it is out there, potentially multiple times, increases the sample set of data available for potentially reverse-engineering the encryption key.
Am I overly concerned? Is it safe to send an encrypted blob of data in a URL like that? Or is that a bad practice? If it is a bad practice, what are the compelling arguments against it?
urlparam=base64encode( AES( (userid | randompassword | expiration), key) ), where key is known only to his server. The link is emailed, the user clicks the link, then the script decrypts the urlparam, and resets the password (if before the expiration). If that's the case, I'm hardpressed to see how a malicious actor could reset a password for another user - especially if integrity verification is used in conjunction with encryption (e.g. AES-GCM). Are you seeing an attack vector here that I'm missing? – mti2935 Mar 31 '21 at 18:37