4 ms·
Cool approach, but I don't see how it could be used to make one-time links. You can invalidate a valid immutable datum; you can only wait until it is expired. T
by doomrobo 12y ago
Cool approach, but I don't see how it could be used to make one-time links. You can invalidate a valid immutable datum; you can only wait until it is expired. To make a link expire immediately after being clicked, you need to store a something server-side.
- kibibu 12y agoYou include the expiry time in the URL and HMAC the URL as well.
- jholman 12y agoI don't think you understand. At a minimum, I don't understand you. The question is not how to make links that expire after a time, the question is how to make links that expire after a fixed number of uses (e.g. one use). Suppose your link expires in 30 minutes (or any other time). What stops me from using that link 30 times, once per minute?
- aptwebapps 12y agomschwaig replied with the answer above [0]: use the old password hash when creating the token. For an example in the wild, see how Django does it[1]. 0. https://news.ycombinator.com/item?id=9055749 https://news.ycombinator.com/item?id=9055749 1. https://github.com/django/django/blob/master/django/contrib/auth/tokens.py https://github.com/django/django/blob/master/django/contrib/...
- jholman 12y agoThank you for the reply, and once I read it enough times in a row, I got it through my thick head. It's still not clear to me, however, how to generalize this technique to create limited-use links that are not necessarily for resetting passwords.
- aptwebapps 12y agoIf you want to have limited-use links that don't cause any writes to the db, then no, you can't with this approach. All it does is use an already necessary db write, the password change, to avoid adding another one, a token.
- mschwaig 12y agoIf you include the current password hash when calculating the hash for the reset link and you also include a random salt in your password hash, the reset link will become automatically invalidated because the password hash will change when a successful reset is performed.
- raziel2p 12y agoI think the point was, if I request a password reset X times for the same email within the duration of the expiration time, there'll be X amount of valid password reset URLs that can potentially be bruteforced. It doesn't matter if the other links are invalidated as long as one of them works. This is solved by rate limiting, I suppose. Feels like something that should've been included in the article.
- aptwebapps 12y ago> I think the point was, if I request a password reset X times for the same email within the duration of the expiration time, there'll be X amount of valid password reset URLs that can potentially be bruteforced. What does this have to do with whether you're storing tokens or using a hash?
- raziel2p 12y agoSorry for the late reply. In the apps I have, I delete any existing tokens for the given e-mail address when a new one is requested, so only one is valid at any given time.
- mschwaig 12y agoI think this problem can also be mitigated by the additional parameters in the reset link like the expration time. If these parametes differ you actually dont get to hash one thing and test it against all currently valid reset URLs to make brute force easier. You could even salt your reset URL deliberately. Of corse, I'm not arguing against rate limiting.
- vidarh 12y agoYou are right that something needs to be stored server side for one-time links. In the password reset example, something is stored: The new password hash. Hence the example of including the old password hash, as a value that will be invalidated when the request has been processed. Otherwise you need to bump a value on accessing the URL, but you still benefit by not having to create book-keeping information when creating the URL.