The password recovery procedure is a major element of security for any web site that contains a login form or any form of authentication. All too often, however, it is left as a minor point of the development stage, and rarely gets a specification of its own, which leads to several security issues, even on major sites.
A good password recovery procedure has to be at the optimal level of compromise between security and usability. When the procedure is too easy to bypass, the security is compromised. When it's too complicated, it unnecessarily annoys the users, who may possibly give up at some point.
This simple rule of best trade-off between security and usability applies to most web sites, but not to some of them where the security needs to be psychologically enhanced. For instance, some categories of web sites (mainly online banks) define an overzealous security strategy, because they need to not only provide security, but also a strong feeling of security to the end-users. Most of the measures dedicated to the creation or recovery of accounts, such as not using email but only postal mail to send any information, sending the login and password in two separate letters, using one-time password generator devices, or just clicking on a random grid to write the password code, are more trouble and additional cost than real security, but it's nevertheless important to create a psychological evidence that the web site is secure. As for a lot of other things, it's not enough to have a secure web site: if the users do not feel the security is at the level they expect it to be, then the procedure may be technically secure, but wrong from a marketing point of view.
I'll detail some techniques commonly used, and finally provide a sample password recovery workflow, suitable for most web sites.
"Click here to receive a new password": this is very very wrong. Resetting a password to something random is not inherently incorrect, but doing it because _someone_ from the internet clicked on a button is not a good pattern. This may result in a denial of service for your users, simply because someone thinks it's funny to request a new password for them (and I'm not even mentionning funny things to do with a script requesting a new password every minute or every day).
The screenshots below are taken from a real site.

"Click here to receive an email that contains a link to reset your password": The user receives, in a mail, not the password but a secure link (https) to a web page where the password can be reset. This is a good trade-off between ease of use and security. The only drawback is that the user receives a weird email every time someone clicks on the button, so you may define some additional restrictions on the action. For instance, only 3 mails per hour, or answer a personal question. Otherwise, it's a strategy I suggest to use in most cases.
"Answer a few question about you": this one is pretty common.
For instance, the Yahoo procedure is the following: ask the login id, a captcha, some birthday information, the country you live in, a postal code, and the middlename or birth date. Wow, that's a lot of questions, so that's secure, right? WRONG. Any of your family members can answer it, and probably most of your friends, former friends, employers, and former employers. That's a crowd! And moreover, thinking about it a little further, imagine that you want to hack the account of someone, how long do you think it would take to collect this information from a co-worker, from a friend, from someone you meet at a bar ? Not more than 5 minutes, on average. Even less after a few drinks.

Note that any person asking me my favourite author will have an immediate answer, that's not something I'm willing to hide, specially if I've forgotten that this is the secret answer I set up a few months ago for my email account... OMG! Now it's published on a blog! I'm so screwed!
"Answer a secret question": a variant from the one above. For instance, Google proposes some "security question": "what is your library card number?", "what was your first phone number?", "what was your first teacher's name", etc, which are all much better than yahoo's (the information required are harder to social-engineer) EXCEPT from people that either can get a physical access to your stuff, or people who actually GOT this information, for instance anyone that was in your circle of friends when you had your first phone number (am I the only one that finds it weird that a security question is based on an information that you actually spent a lot of time spreading around?). So the "security question" should actually be rephrased "security question to prevent people from accessing your account, except when they know you, even remotely". To be honest, I don't really think the library card question is that bad, because it still requires a physical access to a personal object. However, any of my co-workers can easely access my wallet, I don't take it with me when I go to lunch or when a biological urge takes over. Of course, I trust my coworkers, but a good security procedure shall NOT be based on my trust and beliefs, it shall also take into account (at least partially) the fact that I may be social-engineered.
But the worse is still to come, it's the "write your own question". Have you ever had access to a database storing all the "own questions and answers" in plain text ? I did. When you let people choose their questions, not all of them, but a significant number of them, choose something trivial, based on a pun, on a date as complicated as the birth year of their child, or the name of their dog. This is the worst, because you cannot guarantee that the question has any level of security. And yet, you are responsible for the security, because you designed it the way it is.
Anyway, the Google's procedure is not that bad overall, because they actually use the secret question only after 5 days of inactivity on the account, which limits the possibility of hacking to the time periods where people can't access their mail (which means, for most people, during their holidays, when they are at the hospital, on a long trip, or anything else you can easely imagine). Just never leave your google account more than 5 days, and you're secure. The rule itself is a little weird, because it assumes that people are unlikely to be 5 days straight without checking their email, which may be totally correct in the silicon valley, but hardly applies to non-geek people.
So, if the simple rule to apply is "always find the right level of security", how should the typical password recovery workflow be designed ? It depends, of course.
The very first element you have to figure out is the secure perimeter that you are going to use in your user's environement. This secure perimeter defines how you are going to send recovery information, because you trust it against usurpation and disclosure. You don't need to trust it absolutly, just to trust it enough.
For most banks (in Europe at least), the only acceptable perimeter is the physical home of their customers, that's why they generally send the customer information there. Of course, this is not totally secure either, because people can still have their letters stolen, but absolute security does not exist in the real world, and this is the compromise that was defined in their security strategy. For phone operators, it can also be a mobile phone number to which an SMS (Text Message) is sent, it really depends on the data available. For an intranet in a corporate or academic environement, the secure perimeter may be the web administrator office, from whom you personally get a new password (in this case, the procedure often includes 10 minutes of ranting).
For most online sites, the secure perimeter is the email account. Some may argue, but the fact is, it's an acceptable compromise as long as you can admit that if someone can illegally access the user's email account, accessing your web site looks like a minor issue. However, using email as a mean to communicate with the user does not imply sending the recovery information in plain text (the email account may be compromised anytime), that's why it's much better to send a link to a secure password recovery page, rather than actually sending the password itself.
For the most standard cases (of internet web sites), I suggest the following:
Make sure the link is disabled server-side at some point (for instance, using a hashed parameted in the URL, and disable it accordingly in the database after the password was changed, and after a few days in any case).
So, here is the workflow, graphically (click to enlarge):
(the schema was done with balsamiq, a great tool).
Link: http://code.google.com/p/abstractcanvas/
How frustrating is it to have on hand a tool as good as GWT, and still see that all the graphics libraries are tied to the browser! Take for instance chart libraries, it should be obvious that we don't want just some server-side charting engine that can create PNG or PDF, but looks awfully static in the browser, and we don't want either some smart javascript library that looks great in the browser, but can't even create any of the PNG we need to build offline reports. Indeed, we need both.
As it appears there is no such a beast, here is my suggestion to developers using the GWT to create graphics: choose an abstract graphics API, make sure there is an implementation available on both server and client side, and use it to build the next version of your library. That's it. Don't waste your time coding for only one platform when you have at your disposal a technology that can target several ones.
I'm so frustrated with the current situation, that I wrote a proof-of-concept and an example of what should/could be done. Let me introduce you to the AbstractCanvas, a very simple java library that provides a single interface (mainly a subset of the HTML canvas and a few extra methods), and two implementations, one based on the incubator's GWTCanvas, and another one on the standard AWT (but Java2D-powered). There is one single interface to create the graphics, but one just needs to instanciate the AWT implementation to create server-side graphics, or instanciate the GWT implementation to access the client-side counterpart that can dynamically display its data.
As a sample, I also wrote a very simplistic charting engine based on it. Of course, the main point is that the graphics generated server-side are static, but the graphics on the browser are fully dynamic, with some of the bells and whistles one can legitimately expect from a javascript charting engine: using reflection, the engine applies animation and dynamic annotationc when the implementation supports a specific interface.
You can try the demo here

And the project is hosted at Google Code.
A few words on the HTML Canvas implementation: The GWTCanvas provided by the GWT Incubator has a serious limitation on the text drawing (which is actually an understatement to say that there is NO SUPPORT AT ALL for drawing text). There is not such a limitation in the current WHATWG (HTML 5) Canvas specification and in recent Gecko-based (1.9+) browsers, but as long as Microsoft has decided to ignore the HTML Canvas, we're stuck to the limited set of features that are common to all the browsing platforms.
Anyway, to bypass this limitation, I extended the interface to add a basic text support based on some HTML div absolutely positioned above the canvas (on AWT, there is no such a trick, of course). I tried to stick closely to the current HTML5 specs, so when the time comes where the full Canvas API is available on IE as well, it shouldn't be too much trouble to implement it using the standard methods. Or even, to provide another implementation when another solution, better than VML, is found for IE.
The AWT implementation was built on top of Java2D. That was rather easy, the Java2D API already provides everything needed to emulate the Canvas, and I'm pretty satisfied with it, as the resulting graphics are very close to the HTML Canvas implementation of the browsers (on IE, Gecko, and WebKit).
Some screenshots:
Display in the JAVA2D AWT implementation (in a Swing window)

Display in the GWT implementation (IE and Firefox)

Despite the fact that the approach taken is very simple (it took me a few days to write the AWT implementation as well as the charting engine), it works finely (just try the samples).
However, I still wonder if the HTML Canvas is the best approach for the problem: what about using a Flash implementation when the HTML Canvas is not available, instead of the VML-based implementation used by the current GWTCanvas ? The current limitations, namely the poor performance on IE, the lack of text drawing, and the bugged gradient support are really annoying, and a web-wide initiative from the javascript developers, targeting pragmatic solutions, rather than expecting a futuristic standard that would possibly get the approval of Microsoft, would be more than welcome (IMHO).
Recent comments