David Shpritz from the Securabit podcast wrote a short paper aimed at developers on how to build secure password reset functionality.
Highlights:
- Always email a password reset link as another means to verify identity
- Consider use of SMS message for out of band identification (assuming you have Cell # previously stored)
- Secret questions are tricky — personally I say avoid using them
- Never report incorrect username/email error messages on your password lookup page (this allows attackers to harvest emails and determine valid usernames)