Server: Budibase: Unauthenticated user information disclosure via public tenant user lookup endpoint (CVE-2026-73406)
#### Summary The Budibase Worker service exposes a public, unauthenticated API endpoint (`GET /api/global/users/tenant/:id`) that returns sensitive user information including `tenantId`, `userId`, `email`, and `ssoId`. The endpoint is registered in the `PUBLIC_ENDPOINTS` list with a `TODO` comment acknowledging it "should be an internal API." Any unauthenticated party can enumerate user emails or IDs to extract sensitive tenant and user metadata, enabling targeted attacks against multi-tenant deployments. #### Details **Public endpoint registration** at `packages/worker/src/api/index.ts` lines 56-59: ```typescript // TODO: This should be an internal api { route: "/api/global/users/tenant/:id", method: "GET", }, ``` This endpoint is listed in `PUBLIC_ENDPOINTS`, which is passed to `auth.buildAuthMiddleware(PUBLIC_ENDPOINTS)` at line 154. When a request matches a public endpoint pattern, the authentication middleware sets `ctx.publicEndpoint = true` and calls `next()` without performing any authentication (verified at `packages/backend-core/src/middleware/authenticated.ts` lines 124-126, 249-251). All subsequent middleware also skips for public endpoints: - `buildTenancyMiddleware` — passes through - `activeTenant` — passes through - `buildCsrfMiddleware` — skipped for GET methods (line 48 of csrf.ts) - The `budibaseAccess` gate at lines 160-168 explicitly returns `next()` when `ctx.publicEndpoint` is true **Route registration** at `packages/worker/src/api/routes/global/users.ts` line 139: ```typescript loggedInRoutes .get("/api/global/users/tenant/:id", controller.tenantUserLookup) ``` `loggedInRoutes` has no auth middleware group — it is created with `endpointGroupList.group()` (no middleware). **Handler implementation** at `packages/worker/src/api/controllers/global/users.ts` lines 548-562: ```typescript export const tenantUserLookup = async ( ctx: UserCtx<void, LookupTenantUserResponse> ) => { const id = ctx.params.id // is email, check its valid if (id.includes("@") && !emailValidator.validate(id)) { ctx.throw(400, `${id} is not a valid email address to lookup.`) } const user = await userSdk.core.getFirstPlatformUser(id) if (user) { ctx.body = user // Returns full PlatformUser object — no field filtering } else { ctx.throw(400, "No tenant user found.") } } ``` The `id` parameter accepts either an email address (detected by `@` presence) or a user ID. The response returns the **full** `PlatformUser` object from `packages/types/src/documents/platform/users.ts`: ```typescript export interface PlatformUserByEmail extends Document { tenantId: string // Tenant identifier userId: string // Internal user ID } export interface PlatformUserById extends Document { tenantId: string // Tenant identifier email?: string // User email address ssoId?: string // SSO provider identifier } export interface PlatformUserBySsoId extends Document { tenantId: string // Tenant identifier userId: string // Internal user ID email: string // User email address ssoId?: string // SSO provider identifier } ``` The lookup function (`packages/backend-core/src/users/lookup.ts:48-53`) queries the `PLATFORM_USERS_LOWERCASE` CouchDB view with `include_docs: true`, returning the complete platform user document including CouchDB `_id` and `_rev`. **Affected files:** - `packages/worker/src/api/index.ts:56-59` — Public endpoint registration - `packages/worker/src/api/routes/global/users.ts:139` — Route on unauthenticated group - `packages/worker/src/api/controllers/global/users.ts:548-562` — Handler returning full user object - `packages/backend-core/src/users/lookup.ts:48-53` — Platform user lookup with `include_docs: true` - `packages/types/src/documents/platform/users.ts:6-36` — PlatformUser types #### PoC **Static verification:** 1. Observe `packages/worker/src/api/index.ts:56-59`: endpoint in `PUBLIC_ENDPOINTS` with `// TODO: This should be an internal api` 2. Trace handler at `packages/worker/src/api/controllers/global/users.ts:548-562`: no auth checks, returns `ctx.body = user` (full object) 3. Trace middleware chain: all middleware passes through for `ctx.publicEndpoint === true` 4. Confirm no field filtering, sanitization, or authorization between request and response **Dynamic verification (requires running Budibase instance with at least one user):** ```bash # No authentication headers or cookies required # Lookup by email: curl -s http://localhost:4002/api/global/users/tenant/[email protected] # Response (200 OK): # { # "_id": "[email protected]", # "_rev": "1-abc123...", # "tenantId": "tenant-uuid-here", # "userId": "us_uuid-here" # } # Lookup by user ID: curl -s http://localhost:4002/api/global/users/tenant/us_someuserid123 # Response (200 OK): # { # "_id": "us_someuserid123", # "_rev": "1-abc123...", # "tenantId": "tenant-uuid-here", # "email": "[email protected]", # "ssoId": "google-oauth-id"
AI Analysis
Technical Summary
The Budibase Worker service has a public API endpoint GET /api/global/users/tenant/:id intended to be internal but currently accessible without authentication. This endpoint returns the complete PlatformUser object, including tenantId, userId, email, and ssoId, with no filtering or authorization checks. The endpoint is registered in the PUBLIC_ENDPOINTS list, causing the authentication middleware to bypass authentication. The handler accepts either an email or user ID and returns the full user document from CouchDB. This allows unauthenticated attackers to enumerate user emails and IDs, exposing sensitive tenant and user metadata in multi-tenant deployments.
Potential Impact
An unauthenticated attacker can retrieve sensitive user information such as tenant identifiers, user IDs, email addresses, and single sign-on identifiers. This information disclosure could facilitate targeted attacks against tenants or users in multi-tenant environments. The vulnerability does not allow modification or denial of service but exposes confidential data, impacting confidentiality.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until a fix is available, restrict access to the affected endpoint by network controls or reverse proxies to prevent unauthenticated access. Review and update endpoint registration to ensure internal APIs are not publicly accessible. Implement proper authentication and authorization checks on this endpoint to prevent unauthorized data disclosure.
Server: Budibase: Unauthenticated user information disclosure via public tenant user lookup endpoint (CVE-2026-73406)
Description
#### Summary The Budibase Worker service exposes a public, unauthenticated API endpoint (`GET /api/global/users/tenant/:id`) that returns sensitive user information including `tenantId`, `userId`, `email`, and `ssoId`. The endpoint is registered in the `PUBLIC_ENDPOINTS` list with a `TODO` comment acknowledging it "should be an internal API." Any unauthenticated party can enumerate user emails or IDs to extract sensitive tenant and user metadata, enabling targeted attacks against multi-tenant deployments. #### Details **Public endpoint registration** at `packages/worker/src/api/index.ts` lines 56-59: ```typescript // TODO: This should be an internal api { route: "/api/global/users/tenant/:id", method: "GET", }, ``` This endpoint is listed in `PUBLIC_ENDPOINTS`, which is passed to `auth.buildAuthMiddleware(PUBLIC_ENDPOINTS)` at line 154. When a request matches a public endpoint pattern, the authentication middleware sets `ctx.publicEndpoint = true` and calls `next()` without performing any authentication (verified at `packages/backend-core/src/middleware/authenticated.ts` lines 124-126, 249-251). All subsequent middleware also skips for public endpoints: - `buildTenancyMiddleware` — passes through - `activeTenant` — passes through - `buildCsrfMiddleware` — skipped for GET methods (line 48 of csrf.ts) - The `budibaseAccess` gate at lines 160-168 explicitly returns `next()` when `ctx.publicEndpoint` is true **Route registration** at `packages/worker/src/api/routes/global/users.ts` line 139: ```typescript loggedInRoutes .get("/api/global/users/tenant/:id", controller.tenantUserLookup) ``` `loggedInRoutes` has no auth middleware group — it is created with `endpointGroupList.group()` (no middleware). **Handler implementation** at `packages/worker/src/api/controllers/global/users.ts` lines 548-562: ```typescript export const tenantUserLookup = async ( ctx: UserCtx<void, LookupTenantUserResponse> ) => { const id = ctx.params.id // is email, check its valid if (id.includes("@") && !emailValidator.validate(id)) { ctx.throw(400, `${id} is not a valid email address to lookup.`) } const user = await userSdk.core.getFirstPlatformUser(id) if (user) { ctx.body = user // Returns full PlatformUser object — no field filtering } else { ctx.throw(400, "No tenant user found.") } } ``` The `id` parameter accepts either an email address (detected by `@` presence) or a user ID. The response returns the **full** `PlatformUser` object from `packages/types/src/documents/platform/users.ts`: ```typescript export interface PlatformUserByEmail extends Document { tenantId: string // Tenant identifier userId: string // Internal user ID } export interface PlatformUserById extends Document { tenantId: string // Tenant identifier email?: string // User email address ssoId?: string // SSO provider identifier } export interface PlatformUserBySsoId extends Document { tenantId: string // Tenant identifier userId: string // Internal user ID email: string // User email address ssoId?: string // SSO provider identifier } ``` The lookup function (`packages/backend-core/src/users/lookup.ts:48-53`) queries the `PLATFORM_USERS_LOWERCASE` CouchDB view with `include_docs: true`, returning the complete platform user document including CouchDB `_id` and `_rev`. **Affected files:** - `packages/worker/src/api/index.ts:56-59` — Public endpoint registration - `packages/worker/src/api/routes/global/users.ts:139` — Route on unauthenticated group - `packages/worker/src/api/controllers/global/users.ts:548-562` — Handler returning full user object - `packages/backend-core/src/users/lookup.ts:48-53` — Platform user lookup with `include_docs: true` - `packages/types/src/documents/platform/users.ts:6-36` — PlatformUser types #### PoC **Static verification:** 1. Observe `packages/worker/src/api/index.ts:56-59`: endpoint in `PUBLIC_ENDPOINTS` with `// TODO: This should be an internal api` 2. Trace handler at `packages/worker/src/api/controllers/global/users.ts:548-562`: no auth checks, returns `ctx.body = user` (full object) 3. Trace middleware chain: all middleware passes through for `ctx.publicEndpoint === true` 4. Confirm no field filtering, sanitization, or authorization between request and response **Dynamic verification (requires running Budibase instance with at least one user):** ```bash # No authentication headers or cookies required # Lookup by email: curl -s http://localhost:4002/api/global/users/tenant/[email protected] # Response (200 OK): # { # "_id": "[email protected]", # "_rev": "1-abc123...", # "tenantId": "tenant-uuid-here", # "userId": "us_uuid-here" # } # Lookup by user ID: curl -s http://localhost:4002/api/global/users/tenant/us_someuserid123 # Response (200 OK): # { # "_id": "us_someuserid123", # "_rev": "1-abc123...", # "tenantId": "tenant-uuid-here", # "email": "[email protected]", # "ssoId": "google-oauth-id"
CVSS v3.1
Score 7.5high
Affected software
Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.
Weaknesses
AI-Powered Analysis
Machine-generated threat intelligence
Technical Analysis
The Budibase Worker service has a public API endpoint GET /api/global/users/tenant/:id intended to be internal but currently accessible without authentication. This endpoint returns the complete PlatformUser object, including tenantId, userId, email, and ssoId, with no filtering or authorization checks. The endpoint is registered in the PUBLIC_ENDPOINTS list, causing the authentication middleware to bypass authentication. The handler accepts either an email or user ID and returns the full user document from CouchDB. This allows unauthenticated attackers to enumerate user emails and IDs, exposing sensitive tenant and user metadata in multi-tenant deployments.
Potential Impact
An unauthenticated attacker can retrieve sensitive user information such as tenant identifiers, user IDs, email addresses, and single sign-on identifiers. This information disclosure could facilitate targeted attacks against tenants or users in multi-tenant environments. The vulnerability does not allow modification or denial of service but exposes confidential data, impacting confidentiality.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until a fix is available, restrict access to the affected endpoint by network controls or reverse proxies to prevent unauthenticated access. Review and update endpoint registration to ensure internal APIs are not publicly accessible. Implement proper authentication and authorization checks on this endpoint to prevent unauthorized data disclosure.
Technical Details
- Gcve Source
- db.gcve.eu
- Osv Id
- GHSA-hr66-5mqr-8mpx
- Osv Schema Version
- 1.4.0
- Aliases
- []
- Ecosystems
- ["npm"]
- Database Specific Severity
- HIGH
- Cvss Version
- 3.1
Threat ID: 6a65422e9c2644c7f808a5ee
Added to database: 07/25/2026, 23:09:34 UTC
Last enriched: 07/25/2026, 23:56:36 UTC
Last updated: 08/31/2026, 19:02:15 UTC
Views: 47
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.