Skip to content

[Security] User Enumeration via Differential Authentication Error Messages in passportConfig.js #445

@advikdivekar

Description

@advikdivekar

Description:
A CRITICAL security vulnerability exists in backend/config/passportConfig.js at lines 12 and 17. The login endpoint returns two distinct error messages — "Email is invalid" for an unregistered email and "Invalid password" for a wrong password — allowing any unauthenticated attacker to silently enumerate every registered email address with a single request per email.

Impact:
An attacker can send POST /api/auth/login requests for a wordlist of email addresses and, by comparing the response body, determine exactly which emails are registered. Because CORS is currently set to wildcard (*), this enumeration can be run from any webpage with zero browser restrictions. The harvested email list can be used for targeted phishing, credential-stuffing attacks against other services, or to identify high-value accounts.

Steps to Reproduce:

  1. Send POST /api/auth/login with a registered email and wrong password → response body: { "message": "Invalid password" }
  2. Send POST /api/auth/login with an unregistered email and any password → response body: { "message": "Email is invalid" }
  3. Automate across a list of emails — the differential response reveals exactly which accounts exist in the database.

Expected Behaviour:
Both failure cases (unknown email and wrong password) should return an identical generic message such as "Invalid credentials" so no information about account existence is revealed.

Proposed Fix:
In backend/config/passportConfig.js, replace both distinct failure messages with a single generic one:

if (!user) {
    return done(null, false, { message: 'Invalid credentials' });
}
const isMatch = await user.comparePassword(password);
if (!isMatch) {
    return done(null, false, { message: 'Invalid credentials' });
}

Labels: type:bug level:intermediate gssoc:approved gssoc26

Please assign this issue to me under GSSoC 2026. I will open a PR with a complete fix covering all affected files, proper test coverage, and verification steps.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions