Is it safe to send an encrypted blob as a URL parameter?
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?
I don't discuss the security of the password link since I see the problem with your approach even before this link is generated. Your first step after some unauthorized user requested a password reset is to:
Set the password to a temporary, randomly generated password
The problem with this approach is, that a reset of the password of a user can simply be requested by anybody. Based on your description the users password then gets immediately set to some random value, which would immediately deny access to the real user. The user only gets access back if it follows the sent password reset link or triggers their own password reset.
In the mean time an additional step was added to address my concerns:
If Self-Service via the web - require the user to prove that they are the account owner by making them answer their security question
This does not actually prove that they are the account owner. The actual prove for this would be entering the password, which the user no longer has. Answers to security questions instead tend to be easily solvable for others since they a) tend to be simple and b) tend to contain information which can be found on the internet (i.e. Facebook page of user etc). Also, the attacker only needs to know the answer to the security question once in order to reset the password again and again, meaning an effective DoS to the real user.
Also, there is no actual need to reset the password immediately, since the password itself is not known to an attacker. This kind of procedure was only added to make the link simpler, i.e. for technical but not security reasons. But the link can simply contain a username and expiration, signed together with a server side secret. This way the link functions as a time limited request for password change, authorized by the server. The actual changing of the password should only happen once the link was clicked and a new password set by the user.
For more recommendations on this kind of functionality see How to implement “forgot password” functionality?.