We currently have what I believe to be a pretty standard scheme for dealing with password resets. Our reset links are single-use links: They expire immediately after they've been visited, even if the user doesn't actually reset their password.
However, our customers are predominately (99%) businesses with aggressive spam filtering. In particular, some of our biggest customers (school districts) have a spam filters in place that perform link-scanning. They visit [up to N] links in an email as part their algorithms. When users request a password reset, the links are "expired" by the spam filter's visit before the user sees them.
Are there any alternatives to the single-use link that are equally secure? Or that are secure enough to fall within the realm of acceptable practices?
We also need to consider usability. Our customers are generally about as non-technical as you can get. So ideally, the password reset procedure won't become [much] more complicated for the user.
Here's what we've thought of so far:
- Store the reset token in the session. The link would remain active while the original browser session is open and/or the password hasn't actually been reset. It may complicate the process for users who use two different devices for their email and browsing (e.g., email on phone + laptop for browsing).
- Expire the link after N minutes. I think I've seen this. But, I don't know what time limit is an acceptable balance between usable and secure.
- Expire the link only after the form is submitted. Some users may visit the link, putting it into a browser history, but never submit the form. Is that an acceptable level of risk?