What am I missing here? This is what I do;
- User resets password, email link to user
- User clicks link, random temporary password emailed to user
- User logs in with temp password, system then asks them for new password.
This way there is no risk of someone somehow guessing the reset link. Even if they do, all it does is email the user, so they gain nothing...
Random temporary password is a terrible idea. It is both less usable and less secure than sending a secure random token and asking the user to provide a new password. Many users will never change the temporary password. All of them will leave the password in their mail spool. Without even more database signaling, the "resets" will never expire, because they are just passwords.
No - the system first sends the secure random token, then instead of asking them for a new password then, it instead auto-generates a random password and emails it to them.
Then the system FORCES them to change the password when they login with the new password.
Oh - and the tempoary password only valid for 24 hours.
So you get the best of both worlds - without anyone being able to 'guess' anything able to do anything...
The system forces them to change the password if they actually log in. If they don't, the password just sits there. And some users will just cut/paste it.
I'm sure there's a million fiddly things you can do to address the weaknesses of temporary password issuance, but you'd be better off sending a semantically meaningless random token. All the countermeasures you're thinking of here apply identically to the token.
I am advocating for the reset scheme that is the hardest to mess up. Yours is not the hardest to mess up. I'm not trying to get you to change yours.
This way there is no risk of someone somehow guessing the reset link. Even if they do, all it does is email the user, so they gain nothing...