Password reset functionality is one of the most sensitive parts of any application. If the backend fails to validate reset requests properly, the impact can be severe. In this writeup, I am sharing how I found a critical vulnerability in a password reset API that could lead to full account takeover.

For responsible disclosure, I have hidden the target name and redacted all sensitive values.

Summary

While testing the forgot password functionality of a web application, I discovered that the password reset endpoint was not properly validating the reset token. When the reset token was removed from the request, the application did not reject the request. Instead, the server processed the request successfully, changed the password for another random user account, and returned sensitive information belonging to that user in the response.

This behavior could allow an attacker to take over another user's account without having a valid reset token.

Finding the Issue

The issue was discovered during normal testing of the password reset flow. The application sent a password reset link by email, and after opening that link, the final password update request could be intercepted in Burp Suite.

At this stage, the request contained the reset token and the new password. To test server-side validation, I modified the request and removed the reset token value before sending it again.

Instead of returning an error such as invalid token or unauthorized request, the application responded with a success message. Even more critically, the response contained account details of another user. This indicated that the backend was not securely binding the password reset operation to the intended user and was instead applying it to a different account.

Redacted HTTP Request

Below is a simplified redacted version of the request:

PUT /v1/my/profile/reset_password HTTP/2

Host: redacted.example

Content-Type: multipart/form-data; boundary= – – boundary

– – – boundary

Content-Disposition: form-data; name="user[reset_token]"

– – – boundary

Content-Disposition: form-data; name="user[password]"

[REDACTED_PASSWORD]

– – – boundary –

Redacted Response

Instead of rejecting the request, the server returned a successful response and disclosed sensitive user information.

{

. "meta": {

. "status": 200,

. "message": "Success"

. },

. "data": {

. "id": "[REDACTED]",

. "role": "[REDACTED]",

. "email": "[REDACTED]",

. "mobile": "[REDACTED]",

. "profile": {

. "first_name": "[REDACTED]",

. "last_name": "[REDACTED]",

. "full_name": "[REDACTED]"

. }

. }

}

Why This Is Critical

This is a critical issue because the password reset functionality should only work when a valid reset token is provided for the correct account. In this case, removing the token did not stop the password reset request. Instead, the application accepted the request and applied it to another user account.

The response also exposed sensitive information such as user ID, role, email address, phone number, and profile details. This not only confirmed that the password reset had affected another account, but also increased the severity due to information disclosure.

A vulnerability like this can lead to full account takeover because the attacker can set a new password for another user and then log in as that user.

Root Cause

The root cause appears to be missing or broken server-side validation of the password reset token. The backend should strictly verify that the token is present, valid, unexpired, and tied to the correct user account before allowing any password update.

Instead, the application accepted a request with an empty token and processed it against an unintended account.

Expected Behavior

A secure password reset endpoint should immediately reject any request where the reset token is missing, invalid, expired, or tampered with. It should never process the password change, and it should never disclose sensitive user information in the response.

A normal response in this case should be a generic error message only.

Impact

The impact of this issue is severe. An attacker could abuse this flaw to reset another user's password without authorization and fully compromise that account. Since the response also returns sensitive user details, the issue combines account takeover with information disclosure.

Conclusion

This finding shows how dangerous weak validation in password reset functionality can be. A single missing check on the backend can turn a normal recovery feature into a critical account takeover vulnerability.

When testing password reset flows, it is important not only to check whether the token works, but also to see how the application behaves when the token is missing, invalid, or modified. In this case, removing the reset token entirely exposed a serious flaw that could allow unauthorized access to another user's account.

Thnak you!