While intended to be unique (the docs also say it is), the perishable_token is not unique. This can (and does) cause difficult to find bugs where user A tries to reset their password and ends up resetting user B's password if their perishable token is the same.
perishable_token should be either a GUID value, or some combination of time + random to ensure uniqueness.
I've recently had two instances reported to me where a user comes to my site and is authenticated as a different user. I can't reproduce it but I know for certain that it happened based on the user reports. Is this caused by this problem with perishable token not being unique?
I hate devise but I'm going to have to abandon authlogic if there isn't some resolution on this soon.
If you enforce uniqueness in your database, this problem shouldn't happen, right? (And if you choose not to, you'll always be open to a check-and-set race condition.)
I believe we encountered an issue related to this in our production environment. Our password reset system was failing in production for only one user. When I checked the production database, the perishable_token for only this user was not resetting whenever a password reset request was made.
Everything else about the system appeared to be working: The user still received emails containing a link with the perishable_token for the password reset, but since the perishable_token was not updating the user would receive the same expired perishable_token each time.
The problem was only resolved after making another log-in attempt with this account, which then successfully reset the perishable_token. Could this have been as a result of temporary duplicate perishable_tokens, even if no duplicate perishable_token could now be found in the database?
Possibly. But, seriously: Enforce Uniqueness In Your Database.
@davidray if it was regular site-use, sounds like you might have been thinking of persistence_token?
@KelseyDH did you check if the user was valid?? If not, that would have prevented their record from saving with the new perishable token.
The authlogic perishable_token is not the best solution out there. Using something like Rails' message verifier might be a better solution. PRs are welcome :)
That said, authlogic's current perishable_token is 20 bytes generated from a set of 62 possible characters, which should have about 9.7e35 permutations (very unlikely that duplicates could exist).