Skip to content

sec(739): enumeration through login screen#746

Merged
diogomartino merged 2 commits into
Sharkord:developmentfrom
jagobainda:security/739-enumeration-through-login-screen
Jul 4, 2026
Merged

sec(739): enumeration through login screen#746
diogomartino merged 2 commits into
Sharkord:developmentfrom
jagobainda:security/739-enumeration-through-login-screen

Conversation

@jagobainda

Copy link
Copy Markdown
Contributor

Closes #739 the three user-enumeration vectors i found.

Vectors patched

  • Vector 1 — Differentiated error field. Every failure branch now returns { errors: { identity: "Invalid credentials" } }. The password-field error and the invite-specific message are gone.
  • Vector 2 — Ban reason leak. The existingUser.banned check is moved after Bun.password.verify. Without valid credentials the response is indistinguishable from any other failure; the ban reason is still visible to the legitimate account owner.
  • Vector 3 — Timing side-channel. A Bun.password.verify against a precomputed dummy hash is run in the unknown-identity branch, matching the latency (~100–500 ms) of the known-identity path.

Technical decisions

  • GENERIC_LOGIN_ERROR constant — single shared string across the three failure branches to prevent drift via typo.
  • Lazy singleton dummy hashBun.password.hash runs once on the first miss and is reused. If the hash creation rejects, a .catch resets the cached promise so a transient failure cannot turn into a new vector (500 = unknown vs 400 = known).
  • Ban check after verify — an attacker reaching that point already holds the password, so the ban reason is information aimed at the account owner, not the attacker.
  • Server-side logging untouched — the real reason (unknown identity, invalid password, ban) is still logged with the client IP to preserve operational visibility.

Tests

  • Wrong password → identity: "Invalid credentials" (previously password: "Invalid password").
  • Closed registration + unknown identity → same generic error.
  • Banned user with wrong password → ban status is not revealed.
  • Banned user with correct password → ban reason is still exposed (intended behavior).

Side fix

Minor inconsistencies in the client spanish translations (apps/client/src/i18n/locales/es/disconnected.json, settings.json) spotted during diagnosis.

@h8d13

h8d13 commented May 25, 2026

Copy link
Copy Markdown

nice catch on timing hadn't thought of that at all

@jagobainda

Copy link
Copy Markdown
Contributor Author

@h8d13 yeah, it was kinda obvious, in the tests on my production server it was ~10x when the user existed (40ms vs 400ms)

@diogomartino diogomartino 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.

Ty!

@diogomartino diogomartino merged commit c786521 into Sharkord:development Jul 4, 2026
2 checks passed
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.

[Security] Enumeration through login screen

3 participants