After a user has used a password reset token, that token should be burned and should not be used for that account again. The problem is that sometimes developers forget to invalidate these tokens. This would allow several attack avenues such as the attacked being able to generate an infinite amount of tokens because the developer does not invalidate a token after requesting a new one or the attacker could phish a link that might be thought to be expired.
Ensure that generated tokens or codes are:
The referrer header is a header that includes data about the previous webpage that is linked to the current one. Attackers can capture this header if the request is made from the password reset link to their domain. This is a complex attack scenario that is hard to exploit since you have to be able to direct the user from the reset password token page.
Make sure the referrer header does not contain any tokens if it is included in the requests.
Whenever you have a page to reset a password or to request a token, you have to make sure that the endpoint does not respond any differently if the user exists. Otherwise, an attacker could use this information to deduct what users exist and which do not. This means you have to make sure that the response code, body, and even timing are the same. If it takes a while to perform the genuine actions, you have to delay a non-existing user as well.
When creating applications, they often rely on multi-layered architectures. This can create flaws we can abuse if the creator of the system is not careful. By sending HTTP parameters multiple times in strange ways (arrays instead of strings, the same parameter multiple times,…). The server might take the first system to generate a link, using the first email address it encounters but the second system might send that on to the email address of the attacker (the last one in the list).