[SECURITY AUDIT] Username enumeration via login timing side-channel (bcrypt runs only for existing users) #35
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: Low
Confidence: Medium-High (mechanism is clear; real-world exploitability depends on network jitter and is partly blunted by rate limits)
Scope area: Admin login hardening (audit area 1)
What
The login handler short-circuits the password check when the username does not exist:
Because of
&&,bcrypt.compare(users.validatePassword,server/src/model/users/users.model.js:46-49) only runs when the username matches a real account. bcrypt atSALT_ROUNDS = 10costs on the order of ~100ms; a non-existent username returns almost immediately. That measurable difference lets an attacker enumerate valid admin usernames despite the (good) genericIncorrect username or password.message. The same pattern exists in the mobile login path (server/src/router/v1/auth/mobile.controller.js:56-57).Why it matters
The response body is correctly uniform, but the timing is not, defeating the intent of the generic message. Knowing a valid admin username narrows a subsequent credential-stuffing/brute-force campaign. Impact is limited because per-IP backoff, slow-down, and the 10/15-min cap raise the cost of sampling — hence Low — but the enumeration oracle itself is real.
Where
server/src/router/v1/auth/auth.controller.js:51-52server/src/router/v1/auth/mobile.controller.js:56-57server/src/model/users/users.model.js:46-49(validatePasswordreturns early on missing hash)Suggested fix (not implemented)
Always perform a bcrypt comparison against a fixed dummy hash when the user is not found, so both branches take comparable time (a "compare against a constant hash" dummy-work pattern). Keep the generic response unchanged. This equalizes the timing without leaking which factor failed.