On a website I run I have implemented this procedure for account recovery (forgotten password procedure). I would like to know whether there are any issues with it that I have not spotted, that make it insecure.
When the user creates an account, they are required to enter a password (of course) and an email address. They are also required to select a "secret question" from a list of about 20 questions, and enter a "secret answer" to that question. The password and secret question answer are each hashed, each with a different, random salt. Assume that the hashing function used is adequate. (The user can change their email, password and/or secret question/answer at any time, must enter password to do so. I do not impose any password strength requirement, except for a minimum-length requirement.)
If the user needs to recover the account, they go to the account recovery page and enter their user name. An email is sent to the email address associated to their account. This email contains a link which contains a randomly-generated code (site.com/accountrecovery?user=1234&code=bryvthery6y65htee or the like). When the user clicks the link, they are taken back to the site, and assuming the code checks out they are taken to a page where they are asked their secret question and must answer it and at the same time, enter a new password.
Whenever the stored password or secret answer is changed, by whatever method, a new random salt is generated for it.
Are there any issues with this setup that come to mind? I would like constructive criticism. The thinking behind it is that in order to be able to reset the password, the user must have access to the registered email address and must know the secret answer.