Skip to content

Fix SSL cert check on non-standard ports and login user enumeration#3726

Open
sawirricardo wants to merge 2 commits into
bluewave-labs:developfrom
sawirricardo:fix/ssl-port-login-enumeration
Open

Fix SSL cert check on non-standard ports and login user enumeration#3726
sawirricardo wants to merge 2 commits into
bluewave-labs:developfrom
sawirricardo:fix/ssl-port-login-enumeration

Conversation

@sawirricardo

Copy link
Copy Markdown

Summary

Two small fixes for confirmed open issues:

1. SSL/TLS certificate expiry on non-standard HTTPS ports (#3646)

fetchMonitorCertificate was only passing the hostname to ssl-checker, ignoring the port specified in the monitor URL. This meant certificates on non-standard HTTPS ports (e.g., https://example.com:8443) were never checked and always showed "N/A".

Fix: Extract port from the monitor URL and pass it to the ssl-checker via the SSLOptions.port parameter (already supported by the library).

2. Login error handling / user enumeration (#2768)

The login flow returned different error messages and status codes depending on whether the email existed:

  • Non-existent email → "User not found" (404)
  • Wrong password → "Incorrect password" (401)

This leaks information about which emails are registered.

Fix: Catch the "user not found" case and return the same generic "Incorrect email or password" (401) message for both scenarios.

Fixes #3646
Fixes #2768

- Pass port from monitor URL to ssl-checker when checking certificates
  on non-standard HTTPS ports (fixes bluewave-labs#3646)
- Prevent user enumeration in login by returning the same generic error
  for both non-existent email and wrong password (fixes bluewave-labs#2768)

@ajhollid ajhollid left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't actually resolve the enumeration issue noted in the PR title, please see comments.

In future, one issue per PR please 👍

Comment on lines +224 to +228
try {
user = await this.usersRepository.findByEmail(email);
} catch {
throw new AppError({ message: "Incorrect email or password", service: SERVICE_NAME, status: 401 });
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't resolve the enumeration problem. Attackers can still determine if they have found a correct email credential, as bcrypt is still awaited after the user lookup.

If you want to fully resolve the enumeration issue then a dummy value needs to be hashed on the user not found path.

Additionally, this catch block is too broad, it classifies all errors thrown by the repository as email/password errors. This should be narrowed appropriately.

const hostname = monitorUrl.hostname;
const cert = await checker(hostname);
const port = monitorUrl.port ? parseInt(monitorUrl.port, 10) : undefined;
const cert = await checker(hostname, { ...(port ? { port } : {}) });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty convoluted way of expressing that port should not be added here if not specificed.

checker(hostname, port ? { port } : undefined)

seems clearer to me 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SSL/TLS certificate expiry not checked on non standard https port Login error handling issues

2 participants