Our web application sends a one-time use generated token, in the form of an URL, to clients who forget their passwords. This works except for the case where the client is sitting behind another server that scans their email for URLS and does a GET on the URL. I'm assuming the server is checking for a malicious payload.

The client opens the email and clicks on the link, but obviously nothing happens because the token is invalid at that point.

I can think of some ways of handling this:

• Instead of expiring immediately, allow the token to be valid for a certain time period. Disadvantage: This circumvents the whole point of a one-time use token since the token can be used multiple times. Plus it may not solve the problem if the user decides to open their email PAST the expiration time.

• Make the token good for two uses. Disadvantage: similar to the above. What if the spam checker "checks" the URL again... Sigh.

Anyways, I'm looking for some wisdom here on how to handle this. If there are better ideas than what I've proposed I'd love to hear them.

EDIT: I cross-posted this at programmer.stackexchange. Go there for a little more discussion, but the answer I selected below is basically the same answer.


2 Answers 2


The problem you're running into is that GET is supposed to be both "safe" and "idempotent": that is, calling it isn't supposed to make any change on the server, and calling it many times should have the same effect as calling it once. From a standards standpoint, you should be using a POST to use the token.

Obviously, you can't do that from an email. One option is to have the link in the email not actually do anything -- it's just a link to a page that does the real work. Clicking a button or otherwise causing a POST from that page would be the one-time action that expires the token and does whatever your forgotten-password handling involves.


You could try to send not only the token in the e-mail, but also a cookie associated with the token to the browser. On verification both token and cookie must be presented, so the token can only be used successfully with the browser which requested the password reset.

Not the answer you're looking for? Browse other questions tagged .