Password Reset Token Can Be Reused
A password reset link contains a one-time token that should be invalidated immediately after the password is changed. If the token is not marked as used, anyone with access to the original reset link — via email forwarding, a shared inbox, or a previously intercepted email — can trigger another password reset and take over the account.
HighBeginnerSecurity testingManual testingAPI testing
// UNDERSTAND
// Symptoms
- A password reset link works more than once
- After successfully resetting a password, the same reset URL still shows the reset form
- The reset token is not invalidated after the password change is confirmed
- Using the same reset URL a second time does not show an error
// Root Cause
- The reset token is not deleted or marked as used in the database after a successful password change
- Token expiry is checked but used-status is not tracked separately
- Some implementations read and consume the token only on form submission, not on page load — so the reset form renders successfully even for an already-used token when the validity check is deferred to the POST handler
// Where It Appears
- Password reset flows in any authenticated web application
- Account recovery pages
- Shared or forwarded email inboxes and team accounts
- Applications where password reset emails are logged or archived
// REPRODUCE & TEST
// How to Reproduce
- 01Request a password reset for a valid test account
- 02In the test inbox, copy the full reset URL from the email before opening it
- 03Open the reset URL in the browser
- 04Set a new password and complete the reset flow
- 05Paste the original reset URL into a new browser tab
- 06Confirm whether the reset form appears and accepts a new password — it should not
// Test Data Needed
- A valid user account with a working test email address or access to the test inbox
- The original reset link from the email
- The ability to copy and replay the URL after the first use
// Manual Testing Ideas
- Request a reset link, use it to change the password, then try the same link again
- Request two reset links in quick succession; confirm the first is invalidated when the second is issued
- Wait for the token expiry window to pass and confirm it is rejected
- Check whether the token looks guessable (sequential integer, short numeric code)
- Check that the token is at least 32 characters of cryptographically random data
// API Testing Ideas
- Capture the token value from the reset URL before submitting anything
- POST to the password reset endpoint with the captured token to change the password
- POST to the same endpoint again with the same token and a different new password
- Assert the second request returns 400 Bad Request or 422 Unprocessable Entity — not 200 (410 Gone is a defensible alternative but uncommon in practice)
// Automation Idea
Automate a password reset request, extract the token from the test inbox, submit the reset form once, then replay the same token with a second POST request to the reset API. Assert that the second request is rejected with a 400 or 410 response.
// Expected Result
After a password reset token is used to successfully change a password, any subsequent attempt to use the same token should be rejected with a clear error.
// Actual Result (Example)
After successfully resetting the password, navigating to the same reset URL shows the password reset form again and accepts a new password submission.
// REPORT IT
Example Bug Report
- Title
- Password reset link can be reused after a successful password change
- Severity
- High
- Environment
- Staging environment Chrome 124 Standard user account
- Steps to Reproduce
- 01Request a password reset for the test account
- 02Copy the full reset URL from the email before opening it
- 03Open the reset URL in the browser
- 04Set a new password (e.g. TestPass123!) and submit the form
- 05Confirm the success message appears
- 06Open the original reset URL in a new browser tab
- 07Enter a new password and submit the form; confirm the submission is accepted
- Expected Result
- The reset link shows an error such as 'This link has already been used' or redirects to the login page.
- Actual Result
- The password reset form loads normally and accepts a new password, allowing the password to be changed again with the same link.
- Impact
- Anyone with access to the original reset email — via a shared inbox, forwarded email, or archived mail — can use the old link to set a new password and gain full account access.