Forgot Password Returns 200 for Invalid Emails #398

Closed
opened 2026-03-13 07:44:24 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @awesomepandapig on GitHub (Dec 14, 2024).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Send a request to /forget-password with an invalid email (ie: test@example.com).
  2. Receive 200 response instead of 404

image

Current vs. Expected behavior

Following the steps from the previous section I expect to receive an error message indicating that there is no user with the provided email. This in fact, is already the behavior on the server with the following being logged:
[Better Auth] ERROR Reset Password: User not found { email: 'test@example.com' }

I would expect a similar error to be passed in the response to the client so that users are confident that an email was sent.

What version of Better Auth are you using?

1.0.19

Provide environment information

- OS: MacOS 15.1.1
- Browser: Firefox: 133.0

Which area(s) are affected? (Select all that apply)

Server

Originally created by @awesomepandapig on GitHub (Dec 14, 2024). ### Is this suited for github? - [X] Yes, this is suited for github ### To Reproduce 1. Send a request to `/forget-password` with an invalid email (ie: `test@example.com`). 2. Receive `200` response instead of `404` ![image](https://github.com/user-attachments/assets/8ba269ae-1b72-4a7c-96ba-c0c44c57284f) ### Current vs. Expected behavior Following the steps from the previous section I expect to receive an error message indicating that there is no user with the provided email. This in fact, is already the behavior on the server with the following being logged: `[Better Auth] ERROR Reset Password: User not found { email: 'test@example.com' }` I would expect a similar error to be passed in the response to the client so that users are confident that an email was sent. ### What version of Better Auth are you using? 1.0.19 ### Provide environment information ```bash - OS: MacOS 15.1.1 - Browser: Firefox: 133.0 ``` ### Which area(s) are affected? (Select all that apply) Server
GiteaMirror added the bug label 2026-03-13 07:44:24 -05:00
Author
Owner

@Bekacru commented on GitHub (Dec 14, 2024):

this is to avoid leaking unnecessary info. you should display something like: "If the email exists in our database, an email will be sent to your inbox to reset your password."

@Bekacru commented on GitHub (Dec 14, 2024): this is to avoid leaking unnecessary info. you should display something like: "If the email exists in our database, an email will be sent to your inbox to reset your password."
Author
Owner

@awesomepandapig commented on GitHub (Dec 14, 2024):

Hmm... I thought it may be to avoid enumeration attacks, but this conflicts with the signup behavior which responds with an error if the user already exists...
image

@awesomepandapig commented on GitHub (Dec 14, 2024): Hmm... I thought it may be to avoid enumeration attacks, but this conflicts with the signup behavior which responds with an error if the user already exists... <img width="1388" alt="image" src="https://github.com/user-attachments/assets/3eb1ec2b-1108-4d47-8325-b0db98b6b922" />
Author
Owner

@Bekacru commented on GitHub (Dec 14, 2024):

there are cases where email signups are disabled, but you still want users to reset their passwords. email signups are public, so anyone can easily repeatedly attempt to register and determine if an email exists. protecting signup forms against enumeration is almost useless. But, if you’ve disabled email signups and you are using passwords only for logging in after users sign up through another method, or if the system is for internal use, it’s necessary to avoid exposing whether an email exists.

@Bekacru commented on GitHub (Dec 14, 2024): there are cases where email signups are disabled, but you still want users to reset their passwords. email signups are public, so anyone can easily repeatedly attempt to register and determine if an email exists. protecting signup forms against enumeration is almost useless. But, if you’ve disabled email signups and you are using passwords only for logging in after users sign up through another method, or if the system is for internal use, it’s necessary to avoid exposing whether an email exists.
Author
Owner

@lukebarton commented on GitHub (Aug 21, 2025):

there are cases where email signups are disabled, but you still want users to reset their passwords. email signups are public, so anyone can easily repeatedly attempt to register and determine if an email exists. protecting signup forms against enumeration is almost useless. But, if you’ve disabled email signups and you are using passwords only for logging in after users sign up through another method, or if the system is for internal use, it’s necessary to avoid exposing whether an email exists.

I'm not sure you answered @awesomepandapig's point? You say that the forgotten password feature avoids exposing whether the email address exists in the database, but you can easily check if the email exists by trying to signup with the same email and you'll get an "USER_ALREADY_EXISTS" error. It's important to prevent all the leaks, not just some of them. You can prevent the signup from leaking by returning a 200 if someone tries to sign up with the same email address.

@lukebarton commented on GitHub (Aug 21, 2025): > there are cases where email signups are disabled, but you still want users to reset their passwords. email signups are public, so anyone can easily repeatedly attempt to register and determine if an email exists. protecting signup forms against enumeration is almost useless. But, if you’ve disabled email signups and you are using passwords only for logging in after users sign up through another method, or if the system is for internal use, it’s necessary to avoid exposing whether an email exists. I'm not sure you answered @awesomepandapig's point? You say that the forgotten password feature avoids exposing whether the email address exists in the database, but you can easily check if the email exists by trying to signup with the same email and you'll get an "USER_ALREADY_EXISTS" error. It's important to prevent all the leaks, not just some of them. You can prevent the signup from leaking by returning a 200 if someone tries to sign up with the same email address.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#398