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
- Configure any SSO provider and set
ALLOW_EMAIL_LOGIN=false; ensure at least one user has a password set.
- Load the login page — no email/password form is shown, as expected.
- 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>"}'
- Login succeeds (200 + auth cookies) despite email login being "disabled."
What browsers are you seeing the problem on?
No response
Relevant log output
Screenshots
No response
Code of Conduct
What happened?
Setting
ALLOW_EMAIL_LOGIN=falseremoves the email/password form from the login page, but does not disable password authentication on the backend.POST /api/auth/loginstays mounted and neither the route nor the local strategy checks the flag, so a valid email/password sent directly to the API (e.g. viacurl) 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=falsemeaning password login is off — but any account that has a password hash (set before the flag was flipped, via a temporaryALLOW_PASSWORD_RESETwindow, 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.jscomputesemailLoginEnabledfor the frontend onlyapi/server/routes/auth.jsmounts/loginunconditionallyapi/strategies/localStrategy.js/requireLocalAuthnever consult the flagContrast:
ALLOW_REGISTRATIONandALLOW_PASSWORD_RESETare enforced server-side viavalidateRegistration/validatePasswordResetmiddleware —ALLOW_EMAIL_LOGINis the odd one out.Proposed fix (PR to follow)
A
validateEmailLoginmiddleware on the/loginroute, mirroring the existingvalidateRegistration/validatePasswordResetpattern:403whenALLOW_EMAIL_LOGIN=false; unset still defaults to enabledALLOW_EMAIL_LOGIN_OVERRIDEflag preserves the current hidden-but-functional behavior opt-in (e.g. API-only admin login), with each use loggedVersion Information
Reproduced on current
main(96367828e), from source.Steps to Reproduce
ALLOW_EMAIL_LOGIN=false; ensure at least one user has a password set.What browsers are you seeing the problem on?
No response
Relevant log output
Screenshots
No response
Code of Conduct