Skip to content

[Bug]: ALLOW_EMAIL_LOGIN=false only hides the login form — POST /api/auth/login still accepts credentials #14179

Description

@lurkerCha

What happened?

Setting ALLOW_EMAIL_LOGIN=false removes the email/password form from the login page, but does not disable password authentication on the backend. POST /api/auth/login stays mounted and neither the route nor the local strategy checks the flag, so a valid email/password sent directly to the API (e.g. via curl) still returns a session.

Expected: with ALLOW_EMAIL_LOGIN=false, the server rejects password login attempts, matching what the flag advertises to users and admins.

Why this matters

The flag is only enforced client-side (CWE-602). Deployments that are SSO-only rely on ALLOW_EMAIL_LOGIN=false meaning password login is off — but any account that has a password hash (set before the flag was flipped, via a temporary ALLOW_PASSWORD_RESET window, an invite, or an import) can still authenticate through the API. That path bypasses every control living at the identity provider (MFA, conditional access, account disablement), and because the UI reports email login as disabled, no one is watching for it.

Where the gap is

  • api/server/routes/config.js computes emailLoginEnabled for the frontend only
  • api/server/routes/auth.js mounts /login unconditionally
  • api/strategies/localStrategy.js / requireLocalAuth never consult the flag

Contrast: ALLOW_REGISTRATION and ALLOW_PASSWORD_RESET are enforced server-side via validateRegistration / validatePasswordReset middleware — ALLOW_EMAIL_LOGIN is the odd one out.

Proposed fix (PR to follow)

A validateEmailLogin middleware on the /login route, mirroring the existing validateRegistration / validatePasswordReset pattern:

  • 403 when ALLOW_EMAIL_LOGIN=false; unset still defaults to enabled
  • blocked attempts logged with request IP
  • an explicit ALLOW_EMAIL_LOGIN_OVERRIDE flag preserves the current hidden-but-functional behavior opt-in (e.g. API-only admin login), with each use logged

Version Information

Reproduced on current main (96367828e), from source.

Steps to Reproduce

  1. Configure any SSO provider and set ALLOW_EMAIL_LOGIN=false; ensure at least one user has a password set.
  2. Load the login page — no email/password form is shown, as expected.
  3. Send credentials directly to the API:
    curl -X POST <host>/api/auth/login \
      -H 'Content-Type: application/json' \
      -d '{"email":"user@example.com","password":"<valid password>"}'
  4. Login succeeds (200 + auth cookies) despite email login being "disabled."

What browsers are you seeing the problem on?

No response

Relevant log output

NA

Screenshots

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    🐛 bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions