GHSA-cr7p-cr3q-h5cm
## Summary The login lockout mechanism in Budibase creates an observable response discrepancy that allows unauthenticated attackers to enumerate valid email addresses. When an existing user's account is locked after 5 failed login attempts, the server returns a distinct `403` response with `X-Account-Locked: 1` and `Retry-After: 900` headers plus the message "Account temporarily locked." For non-existing users, the response is always a generic `403 "Unauthorized"` regardless of attempt count, because the lockout counter is never incremented. ## Details The vulnerability exists in two files that implement the login lockout feature: **`packages/worker/src/middleware/lockout.ts:18-36`** — The lockout middleware only blocks requests for users that exist in the database AND are locked: ```typescript export default async (ctx: Ctx, next: Next) => { const email = ctx.request.body.username if (!email) { return await next() } const dbUser = await userSdk.db.getUserByEmail(email) if (dbUser && (await isLocked(email))) { // line 26: non-existing users skip this entirely ctx.set("X-Account-Locked", "1") ctx.set("Retry-After", String(env.LOGIN_LOCKOUT_SECONDS)) ctx.throw(403, "Account temporarily locked. Try again later.") } return await next() } ``` **`packages/worker/src/api/controllers/global/auth.ts:127-141`** — The login handler only increments the failure counter for existing users: ```typescript if (err || !user) { if (dbUser) { // line 129: non-existing users never trigger onFailed() await onFailed(email) } if (await isLocked(email)) { return handleLockoutResponse(ctx, email) } // ... return passportCallback(ctx, user as any, err, info) } ``` **Execution flow for existing users (after 5 failed attempts):** 1. `lockout` middleware → `getUserByEmail` returns user → `isLocked` returns true → 403 + `X-Account-Locked: 1` + `Retry-After: 900` + "Account temporarily locked" **Execution flow for non-existing us
Properties
- ghsa_id
- GHSA-cr7p-cr3q-h5cm
- severity
- medium
- summary
- Budibase: Account Enumeration via Login Lockout Response Differential
- cvss_score
- 5.3
- cve_id
- GHSA-cr7p-cr3q-h5cm
- cvss_vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
- is_ghsa_only
- true
- ghsa_published
- 2026-07-24T21:43:11Z
- source_url
- https://github.com/advisories/GHSA-cr7p-cr3q-h5cm
- ghsa_updated
- 2026-07-24T21:43:15Z
Related Entities (4)
REPORTED_BY (1)
VULNERABLE_TO (1)
AFFECTS (1)
HAS_WEAKNESS (1)
Explore deeper with Ninja Signal's threat intelligence graph