Comment on page
🛠️ Password reset
Websites that manage user accounts usually have a "forgot password" or "reset password" feature. This offers attackers an interesting vector as it could potentially lead to Account Takeover (ATO).
When this feature is present on a website, there a a few things to check.
- Is there a captcha, rate-limit or any other anti-DoS mitigation?
- Is there any kind of validation, from the user, that the password must be reset? This could lead to a kind of DoS on user accounts if there isn't.
- Is the feature relying on security questions that could be easily answered from OSINT or Social Engineering?
- Is the previous password sent in clear-text to the user, indicating that the passwords are not stored in a hashed format?
- If a one-time password (OTP) is sent to proceed with the password reset, is it sent on a secure channel (e.g. mitigating MitM)?
- Can the feature be used by attackers to enumerate users (e.g. error message when trying to proceed with a user that doesn't exist)?
- Is there a password reset link sent? If so:
- Is it still valid after a reset?
- Does it have an expiry date? If so, is it still valid after that period of time?
- Is the link fully random or is there any guessable format that can be reproduced to takeover other accounts?
///// WIP below
To provide the user with a link to reset its password, some implementations use the result of input headers such as the
Hostheader. This helps in constructing a resetting password link by keeping the origin (
example.com). By manually changing the
Hostheader and using a malicious origin (
malicious.com), the user is redirected to malicious.com when clicking the link.
This vulnerability is easy to test.
- 1.Send a request to a forget password mechanism using your own email.
- 2.Change the Host header between the requests
- 3.Check the resetting password link you received via email. If the value of the
Hostheader is reflected in the origin in the link (
https://www.malicious.com/reset-link.php?token=$TOKEN_VALUE, then it's vulnerable
Refererheader contains information about the previous web page from which a request has been made. It
example1.comhas a link pointing to
example2.com, when clicking on that link, the
Refererheader will be set to
Refererheader will print out the whole URL, containing query parameters and so on, not just the origin.
Referrer-Policywith the directive
no-referrermitigates the issue.
To test for token leakage:
- 1.The forgot password mechanism has to be used with a valid email address.
- 2.After clicking on the reset password link (received by email), the password shouldn't be changed.
- 3.Upon clicking on the reset password link, it's important to click on another link from another origin.
- 4.By intercepting the request, one can check if the
Refererheader (if set), contains the token.
In a real-world situation, the "other" origin should be vulnerable for an attacker to intercept the token (from the
When clicking on a reset password button, a request can be sent with a parameter such as
email=$EMAIL. By modifying this parameter, multiple tests can be done to take over the account requesting a reset password.
The same can be done when the request uses an API: