Security

    Account enumeration in mobile app login flows

    A 2026 view of an attacker probing a mobile app's login and password-reset API and learning which accounts exist from distinct error messages and response timing

    Account enumeration is a subtle leak that makes other attacks easier: your login, signup, or password-reset flow quietly tells an attacker whether a given email has an account, and they use that to build a list of valid accounts to target. It usually shows up in small differences, a "user not found" message versus "wrong password," a signup that rejects an existing email distinctly, a response that returns faster for known accounts. None of it exposes data directly, but it hands attackers a head start on credential stuffing and phishing. Here is what account enumeration is, where it leaks, and how to prevent it.

    Short answer

    Account enumeration is when your app's authentication flows reveal whether an account exists for a given email or username, letting an attacker compile a list of valid accounts to target with phishing, credential stuffing, or brute force. Per OWASP, it leaks through distinct error messages, different response timing, or distinct behavior across login, signup, and password-reset flows. The fix is to make responses uniform: use generic messages that do not confirm or deny an account's existence, keep timing consistent, and rate-limit the endpoints. Because the app talks to an API an attacker can call directly, these protections must live on the server, where the responses are generated.

    What you should know

    • Enumeration reveals which accounts exist: without exposing their data directly.
    • It enables follow-on attacks: targeted phishing, credential stuffing, brute force.
    • It leaks via differences: error messages, timing, or behavior.
    • Use uniform responses: do not confirm or deny an account's existence.
    • Enforce on the server: the API is what an attacker queries.

    What is account enumeration?

    It is determining which accounts exist by observing how your system responds. An attacker submits emails or usernames to your login, signup, or password-reset flows and watches for any difference that distinguishes a real account from a non-existent one. If the system behaves differently for the two, says "no such user" versus "wrong password," rejects a signup for an existing email with a distinct message, or returns a password-reset response that confirms whether the email is registered, the attacker learns which accounts are valid. The data itself is not exposed, but the knowledge of which accounts exist is valuable: it lets an attacker focus credential-stuffing and brute-force attempts on real accounts, and craft targeted phishing at confirmed users. So enumeration is a precursor that makes the attacks that follow more efficient.

    Where does account enumeration leak?

    In the differences between how your flows respond. The table lists the common spots.

    FlowHow it leaks
    LoginDistinct messages for unknown user versus wrong password
    SignupA distinct error when an email is already registered
    Password resetConfirming or denying whether the email exists
    Response timingFaster or slower responses for known accounts
    Error codes or fieldsDifferent status or response shape per case

    The recurring pattern is any observable difference between a real and a fake account. Login is the classic case, where a helpful "we don't recognize that email" tells the attacker more than they should learn. Password reset is another, since a flow that says "no account with that email" confirms non-existence and one that says "email sent" confirms existence. Even when messages are uniform, response timing can leak, if checking a real account takes a different amount of time than a fake one.

    How do you prevent it?

    Make the response the same whether or not the account exists, and rate-limit. For login, return a generic failure like "invalid credentials" that does not distinguish an unknown user from a wrong password. For password reset, always respond the same way, such as "if an account exists for this email, we have sent reset instructions," regardless of whether the email is registered. For signup, handle an existing email without a distinct, enumerable response where possible, for example by sending a notification to the existing address rather than telling the requester it is taken. Keep response timing consistent so it does not reveal the difference, and rate-limit and monitor these endpoints to slow bulk enumeration. Balance this against usability, since some friction is the tradeoff, and enforce all of it on the server, since the attacker queries the API directly. The goal is that observing your responses tells an attacker nothing about which accounts exist.

    What to watch out for

    The first trap is helpful login or reset messages that distinguish a known account from an unknown one; use uniform, generic responses. The second is timing differences that leak existence even when messages match; keep timing consistent. The third is a signup flow that plainly states an email is already registered, which confirms the account. Account enumeration is a server-side behavior, so it is fixed and tested on your backend, but a pre-submission scan such as PTKD.com (https://ptkd.com) reads your app against OWASP MASVS and surfaces the authentication endpoints your app calls, a useful inventory of the flows to review for enumeration. The response design lives on your server.

    What to take away

    • Account enumeration is your authentication flows revealing whether an account exists, which lets attackers target real accounts with phishing, credential stuffing, and brute force.
    • It leaks through distinct error messages, response timing, or behavior across login, signup, and password-reset flows.
    • Prevent it with uniform responses that do not confirm or deny an account, consistent timing, and rate limiting, enforced on the server.
    • Use a pre-submission scan such as PTKD.com to inventory the authentication endpoints your app calls, then review them for enumeration on the server.
    • #account-enumeration
    • #authentication
    • #login
    • #api-security
    • #owasp
    • #app-security
    • #mobile

    Frequently asked questions

    What is account enumeration?
    It is determining which accounts exist by observing how your system responds to submitted emails or usernames in login, signup, or password-reset flows. If the system behaves differently for a real account than a fake one, through messages, timing, or behavior, an attacker learns which accounts are valid. The data is not exposed, but knowing which accounts exist lets an attacker focus credential stuffing and brute force on real accounts and craft targeted phishing, so it is a precursor that makes follow-on attacks more efficient.
    Where does account enumeration leak?
    In any observable difference between a real and a fake account. Login is the classic case, with distinct messages for an unknown user versus a wrong password. Password reset leaks when it confirms or denies whether an email is registered. Signup leaks with a distinct error for an already-registered email. And even with uniform messages, response timing can leak existence if checking a real account takes a different amount of time. Different status codes or response shapes can leak too.
    How do I prevent account enumeration?
    Make the response the same whether or not the account exists. For login, return a generic failure like invalid credentials that does not distinguish unknown user from wrong password. For password reset, always respond the same way regardless of whether the email is registered. Handle signup of an existing email without an enumerable response where possible. Keep timing consistent so it does not leak, rate-limit and monitor the endpoints, and enforce all of this on the server.
    Why must enumeration defenses be server-side?
    Because the attacker queries your API directly, not through your app's UI. The app talks to an authentication API that anyone can call and observe with ordinary tools, so the responses, messages, status codes, and timing, are generated by the server and that is where the differences leak. Making the app's UI uniform does nothing if the underlying API responds differently for real and fake accounts. The uniform responses, consistent timing, and rate limiting must be implemented on the backend.
    Can a scan detect account enumeration?
    It is a server-side behavior, so it is fixed and tested on your backend rather than found by inspecting the app binary. However, a pre-submission scan such as PTKD.com reads your app against OWASP MASVS and surfaces the authentication endpoints your app calls, which is a useful inventory of the flows, login, signup, password reset, to review for enumeration. You then verify, on the server, that those endpoints respond uniformly and with consistent timing regardless of whether an account exists.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free