iTranslated by AI
Why Supabase, Firebase, and Auth0 Obfuscate Authentication Errors
Introduction
In my previous article, "Why Login Error Messages Are Made Ambiguous", I discussed account enumeration attacks, where providing distinct feedback for invalid emails versus incorrect passwords allows attackers to determine if an account exists.
Following up on that, this article explores how authentication platforms like Supabase, Firebase, and Auth0 handle this issue, and what you should be mindful of during sign-up and password reset processes.
Why BaaS/IDaaS Authentication Errors Are Designed Ambiguously
BaaS (Backend as a Service) provides backend functionalities like authentication, databases, and storage, allowing you to use them without building them from scratch.
While I refer to them as BaaS for convenience in this article, Auth0 is strictly an IDaaS/CIAM authentication platform. Supabase and Firebase are BaaS that include databases and storage.
Major BaaS/IDaaS providers adopt a design that returns vague error messages or generic error codes that make it difficult for external actors to distinguish whether an email address does not exist or if a password is incorrect. This ensures that even if users do not have a deep understanding of security design, the system behaves safely by default.
In other words, the fact that BaaS authentication errors seem "unfriendly" is not a design flaw, but an intentional security design choice.
Supabase: Invalid login credentials
In Supabase Auth's signInWithPassword, if email/password authentication fails, it does not distinguish between a non-existent user or an incorrect password, generally returning Invalid login credentials.
This behavior originates from the response of the Supabase Auth API (the GoTrue-based backend) rather than just client-side processing.
For example, depending on the environment, you might see a response like this:
{
"code": "invalid_credentials",
"message": "Invalid login credentials"
}
Therefore, it is natural to display a generic message like "The email address or password is incorrect" on the login screen.
Firebase: From "Distinguishing" to "Unifying"
In Firebase Authentication and Google Cloud Identity Platform, there were cases where you could distinguish between a non-existent user and an incorrect password during authentication failure.
| Old Error Code | Meaning |
|---|---|
EMAIL_NOT_FOUND / auth/user-not-found
|
Email address is not registered |
auth/wrong-password |
Password is incorrect |
While user-friendly, this allows attackers to guess the existence of email addresses, posing a risk of account enumeration attacks.
To address this, Firebase/Identity Platform offers Email Enumeration Protection. It is enabled by default for projects created on or after September 15, 2023.
When enabled, failed sign-ins are unified into generic INVALID_LOGIN_CREDENTIALS errors, making it difficult to distinguish between non-existent emails and incorrect passwords.
| New Error Code | Meaning |
|---|---|
INVALID_LOGIN_CREDENTIALS |
Email or password is incorrect (no distinction) |
Firebase/Identity Platform includes countermeasures against email enumeration attacks as a standard configuration.
Auth0: Designing to Prevent Account Identification
To prevent account enumeration attacks, Auth0 officially recommends designing authentication and sign-up flows that make it difficult to determine account existence.
In Passwordless connections, enabling Disable Sign Ups restricts access to existing users only; however, since this can potentially make you vulnerable to account enumeration, the Auth0 documentation recommends against it.
Auth0 also provides security features like Bot Detection, Suspicious IP Throttling, and Brute Force Protection, which are designed to be used together to mitigate authentication attacks.
What This Means for BaaS Users
You may have felt frustrated by BaaS returning "vague" errors. However, in many cases, this is not a lack of friendliness, but a design meant to prevent account enumeration attacks.
In short, the Invalid login credentials from Supabase is not merely unfriendly, but a behavior intended to make user existence difficult to distinguish from the outside.
If you implement your own authentication and return detailed errors to be "user-friendly," your resistance to account enumeration attacks may be weaker than the standard BaaS behavior. Even when implementing custom authentication, it is safe to start by referencing the standard behavior of BaaS.
📚 References for this chapter
The Same Trap in Sign-up and Password Reset
Even if your login screen is perfectly secured, if you allow "existence verification" on the sign-up or password reset screens, account enumeration attacks will still succeed. You must apply the same philosophy across all screens related to authentication, not just the login page.
Sign-up Screen
| Design | Displayed Message | Assessment |
|---|---|---|
| ❌ NG | "This email address is already registered" | Attackers can verify existence via the sign-up form |
| ✅ OK | "A registration email has been sent. Please check your email" | Does not distinguish existence on-screen. Provide guidance for existing users via a separate channel if necessary |
Implementation concept for the OK pattern:
- New users → Normal registration email (confirmation link)
- Existing users → If necessary, send a guidance email saying "You are already registered. Click here to log in."
- The screen display is identical in both cases: "Email has been sent"
This prevents attackers from verifying account existence on the sign-up screen while providing existing users with an opportunity to realize their status through a different channel (email).
Password Reset Screen
| Design | Displayed Message | Assessment |
|---|---|---|
| ❌ NG | "This email address is not registered" | Attackers can verify existence |
| ✅ OK | "Email sent to the specified address" (Same display even if not registered) | Do not send emails to non-existent addresses / Send reset links to registered addresses |
The screen display is the same regardless of whether the account exists, so the attacker cannot distinguish the two.
UX Issues When Emails Do Not Arrive
The design of always returning "Email sent" for password resets has side effects.
Users who enter a non-existent email address will never receive an email no matter how long they wait. This leads to UX confusion, as they cannot determine if their address is wrong, if the email is lost, or if the server is down.
Here are some countermeasures:
- Place a link to "What to do if you don't receive the email" on the email sent confirmation screen (pointing to a sign-up page or FAQ)
- Provide a contact form if the email doesn't arrive within a few minutes
- Supplement UX through help flows without sacrificing security
Consistency Across All Screens
If you allow existence verification on even one screen—be it login, sign-up, or password reset—attackers will exploit it. Maintaining consistent messages and responses across all screens is a prerequisite for defending against account enumeration attacks.
2 📚 References for this chapter
2 - OWASP Authentication Cheat Sheet (Authentication and Error Messages)
2 - OWASP Forgot Password Cheat Sheet
UX and Security Trade-off
After reading this far, you might have the following questions from a user's perspective:
2 "Aren't ambiguous messages unfriendly to users?" "Aren't you sacrificing UX?"
I believe this question is valid, as there is an architectural trade-off between security and UX. I have summarized the decision-making criteria below.
Ambiguous Messages During Authentication Are the Standard for B2C
In B2C services accessed by an unspecified number of users (SNS, EC, consumer apps, etc.), you cannot distinguish between attackers and legitimate users. Since anyone can access the login screen, it is standard practice to make authentication messages ambiguous.
Exceptions May Exist for B2B / Internal Tools
In business systems or internal tools, there are cases where "verifying account existence" is a business requirement.
- Administrators want to check if "this email address has already been invited to the team"
- In B2B SaaS, members of the contracting company want to check via the management screen if users have successfully logged in
If the attacker's entry point is limited (internal VPN, IP restriction, etc.), prioritizing convenience may be a valid judgment.
However, allowing detailed errors solely because "it is B2B" or "it is an internal tool" is dangerous. You can only make an exception if you can design-wise explain that attackers cannot reach that screen due to VPNs, IP restrictions, SSO, audit logs, or rate limiting. Even if you think it's an internal tool and thus safe, there are cases where it was actually reachable from the internet, a former employee account remained, or IP restrictions were insufficient.
Replace "Friendly Messages" with "Friendly Flows"
There are ways to ensure security without sacrificing UX. It is a paradigm shift: Keep messages ambiguous, but flows friendly.
| Scenario | Friendly Message (NG) | Friendly Flow (OK) |
|---|---|---|
| Login Failure | "The email address is incorrect" | Generic message + Link to "Sign up if you don't have an account" |
| Password Reset Complete | "Not registered" | "Email sent to the address" + FAQ link for "What to do if it doesn't arrive" |
| Sign-up Complete | "Already registered" | "Email sent" + Provide opportunity for existing users to notice via a separate channel (email) |
By providing paths to help resources, users can reach solutions on their own. It is possible to design a flow that is user-friendly for the next action without allowing existence verification.
Summary of Decision Criteria
When in doubt, think in this order:
- Is the service B2C or B2B? (If B2C, prioritize ambiguity)
- Are attacker entry paths limited? (If limited, convenience can be considered)
- Can UX be supplemented by help flows? (If so, aim for a balance with ambiguity)
When unsure, prioritize not leaking existence verification and supplement lacking UX through help flows.
Conclusion
Authentication errors in major BaaS/IDaaS (Supabase, Firebase, Auth0) are crafted ambiguously as an industry-standard design to prevent account enumeration attacks. The fact that BaaS returns "unfriendly"-looking errors is not a design flaw, but an intended result.
Takeaways
- Use BaaS behavior as the "minimum baseline": If you give up on ambiguity in custom implementations, your security resistance may fall below that of BaaS
- Consistency across all screens: If you allow existence verification on even one screen—login, sign-up, or password reset—the entire defense collapses
- Reinforce UX with "friendly flows": While keeping messages ambiguous, ensure UX through help resources, FAQs, and sign-up prompts
To Designers
Authentication error design does not end at the login screen.
You need to monitor whether you are leaking existence verification, including in sign-up and password reset processes.
I intend to continue aiming for balanced designs where messages are ambiguous but flows are user-friendly.
Discussion