0

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 (i.e. the spam 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.

  • IMO you should combine invalidation on password change (POST, see Bart's answer) with an expiry time (24h or so). If the user opens the email too late they simply need to request another email. – CodesInChaos Oct 4 '14 at 7:44
  • 4
    No, you really should not invalidate on GET. That breaks the whole point of GET. What if the client simply refreshes their page? Either time out or invalidate on POST. – david.pfx Oct 4 '14 at 14:04
  • Is the mail server using a specific user agent? or does it look like something coming from an actual browser? – user40980 Oct 4 '14 at 17:41
6

Those anti-spam servers probably assume that the HTTP GET method is idempotent,which means that each time you use that method on a URL, you get the same result back. Unfortunately for you, this is also how that method is specified in the HTTP standard.

One way to get one-time use tokens to work is to count only when you receive a POST to that URL. This would work like this:

  • You send the URL with the one-time use token to your client
  • When they click on the URL (or when some process accesses it with a GET request), you send back a simple page with a form or button to reset or change their password.
  • When the user presses the button or submits the form, the page sends a POST request to the page's URL (i.e. the one-time use token URL). This would constitute the one use allowed for the token.
  • After having received the POST, you can either invalidate the URL altogether (all requests get a 404 response) or you can stop responding to POST requests, at your discretion.
  • I don't think the form should only have that single button, it should ask for the new password. Change the password when pressing the submit button and invalidate the token at the same time. – CodesInChaos Oct 4 '14 at 7:47
  • @CodesInChaos: I have added it as an option to my answer. – Bart van Ingen Schenau Oct 4 '14 at 11:08
  • Great answer. Exactly what I was looking for. Thanks! – Avery Chan Oct 6 '14 at 1:07
0

Instead of sending a url, send a url and a confirmation code that's not part of the URL You can still make the combo good for just one use, and for a limited amount of time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.