Every CVE Search/ Get API key

CVE-2026-45716

Budibase: Builder-to-Admin Privilege Escalation via onboardUsers Endpoint Without SMTP Configuration

8.8 HighFix available

Budibase is an open-source low-code platform. Prior to 3.38.1, the POST /api/global/users/onboard endpoint is protected by workspaceBuilderOrAdmin middleware, allowing any user with builder permissions to access it. When SMTP email is not configured (the default for self-hosted Budibase instances), this endpoint bypasses the admin-restricted invite flow and directly creates users via bulkCreate, accepting arbitrary admin and builder role assignments from the request body. A builder-level user can create a new global admin account and receive the generated password in the response, achieving full privilege escalation. This vulnerability is fixed in 3.38.1.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

0.26%Up 0.2 points since May 28, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.8

Budibase: Builder-to-Admin Privilege Escalation via onboardUsers Endpoint Without SMTP Configuration

Budibase is an open-source low-code platform. Prior to 3.38.1, the POST /api/global/users/onboard endpoint is protected by workspaceBuilderOrAdmin middleware, allowing any user with builder permissions to access it. When SMTP email is not configured (the default for self-hosted Budibase instances), this endpoint bypasses the admin-restricted invite flow and directly creates users via bulkCreate, accepting arbitrary admin and builder role assignments from the request body. A builder-level user can create a new global admin account and receive the generated password in the response, achieving full privilege escalation. This vulnerability is fixed in 3.38.1.

Record
CVE-2026-45716
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269
Updated
2026-11-02
EUVDEUVD-2026-32602 8.8

Budibase is an open-source low-code platform. Prior to 3.38.1, the POST /api/global/users/onboard endpoint is protected by workspaceBuilderOrAdmin middleware, allowing any user with builder permissions to access it. When SMTP email is not configured (the default for self-hosted Budibase instances), this endpoint bypasses the admin-restricted invite flow and directly creates users via bulkCreate, accepting arbitrary admin and builder role assignments from the request body. A builder-level user can create a new global admin account and receive the generated password in the response, achieving full privilege escalation. This vulnerability is fixed in 3.38.1.

Record
EUVD-2026-32602
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-c54j-xp92-wh28 8.8

Budibase: Builder-to-Admin Privilege Escalation via onboardUsers Endpoint Without SMTP Configuration

Summary

The POST /api/global/users/onboard endpoint is protected by workspaceBuilderOrAdmin middleware, allowing any user with builder permissions to access it. When SMTP email is not configured (the default for self-hosted Budibase instances), this endpoint bypasses the admin-restricted invite flow and directly creates users via bulkCreate, accepting arbitrary admin and builder role assignments from the request body. A builder-level user can create a new global admin account and receive the generated password in the response, achieving full privilege escalation.

Details

The vulnerability stems from a mismatch between the authorization level of the onboardUsers endpoint and the user-creation capabilities it exposes when SMTP is not configured.

Route definition (packages/worker/src/api/routes/global/users.ts:93-109):

builderOrAdminRoutes  // <-- allows builders, not just admins
  .post(
    "/api/global/users/onboard",
    buildInviteMultipleValidation(),
    controller.onboardUsers
  )

Compare with the invite and inviteMultiple endpoints which are correctly admin-only:

adminRoutes  // <-- admin only
  .post("/api/global/users/invite", buildInviteValidation(), controller.invite)
  .post("/api/global/users/multi/invite", buildInviteMultipleValidation(), controller.inviteMultiple)

Controller (packages/worker/src/api/controllers/global/users.ts:601-630):

export const onboardUsers = async (ctx) => {
  if (await isEmailConfigured()) {
    await inviteMultiple(ctx)  // admin-only path (delegates to invite flow)
    return
  }

  // No SMTP → directly create users with attacker-controlled roles
  const users = ctx.request.body.map(invite => {
    const password = generatePassword(12)
    createdPasswords[invite.email] = password
    return {
      email: invite.email,
      password,
      forceResetPassword: true,
      roles: invite.userInfo.apps || {},
      admin: { global: !!invite.userInfo.admin },  // <-- attacker-controlled
      builder: invite.userInfo.builder,              // <-- attacker-controlled
      tenantId: tenancy.getTenantId(),
    }
  })

  let resp = await userSdk.db.bulkCreate(users)
  for (const user of resp.successful) {
    user.password = createdPasswords[user.email]  // <-- password returned!
  }
  ctx.body = { ...resp, created: true }
}

Middleware pass-through (packages/backend-core/src/middleware/workspaceBuilderOrAdmin.ts:10-26):

In the worker context (env.isWorker() is true), when there is no workspaceId parameter in the request (which there isn't for the onboard endpoint), the middleware at line 19 checks !workspaceId && env.isWorker() — this is true, so it falls through to line 21 which only checks hasBuilderPermissions. Any global builder passes.

Validation gap (buildInviteMultipleValidation at line 37-45): The Joi schema validates userInfo as Joi.object().optional() with no constraints on its contents, so admin and builder fields pass through.

No downstream check: bulkCreate and buildUser do not strip or validate admin/builder fields — they are written directly to the user document in CouchDB.

PoC

Prerequisites: A self-hosted Budibase instance (default: no SMTP configured) and a user account with builder-level access.

Step 1: Authenticate as a builder user and obtain the session cookie:

# Login as builder
curl -s -c cookies.txt -X POST 'http://localhost:10000/api/global/auth/default/login' \
  -H 'Content-Type: application/json' \
  -d '{"username":"[email protected]","password":"builderpassword"}'

Step 2: Create a new global admin user via the onboard endpoint:

curl -s -X POST 'http://localhost:10000/api/global/users/onboard' \
  -H 'Content-Type: application/json' \
  -b cookies.txt \
  -d '[{"email":"[email protected]","userInfo":{"admin":{"global":true}}}]'

Expected response (includes the…

Record
GHSA-c54j-xp92-wh28
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269
Updated
2026-11-02
NVD 8.8

Budibase is an open-source low-code platform. Prior to 3.38.1, the POST /api/global/users/onboard endpoint is protected by workspaceBuilderOrAdmin middleware, allowing any user with builder permissions to access it. When SMTP email is not configured (the default for self-hosted Budibase instances), this endpoint bypasses the admin-restricted invite flow and directly creates users via bulkCreate, accepting arbitrary admin and builder role assignments from the request body. A builder-level user can create a new global admin account and receive the generated password in the response, achieving full privilege escalation. This vulnerability is fixed in 3.38.1.

Record
CVE-2026-45716
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269
Updated
2026-11-02
OSV 8.8

Budibase: Builder-to-Admin Privilege Escalation via onboardUsers Endpoint Without SMTP Configuration

Budibase is an open-source low-code platform. Prior to 3.38.1, the POST /api/global/users/onboard endpoint is protected by workspaceBuilderOrAdmin middleware, allowing any user with builder permissions to access it. When SMTP email is not configured (the default for self-hosted Budibase instances), this endpoint bypasses the admin-restricted invite flow and directly creates users via bulkCreate, accepting arbitrary admin and builder role assignments from the request body. A builder-level user can create a new global admin account and receive the generated password in the response, achieving full privilege escalation. This vulnerability is fixed in 3.38.1.

Record
CVE-2026-45716
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269
Updated
2026-11-02
OSVGHSA-c54j-xp92-wh28 8.8

Budibase: Builder-to-Admin Privilege Escalation via onboardUsers Endpoint Without SMTP Configuration

Summary

The POST /api/global/users/onboard endpoint is protected by workspaceBuilderOrAdmin middleware, allowing any user with builder permissions to access it. When SMTP email is not configured (the default for self-hosted Budibase instances), this endpoint bypasses the admin-restricted invite flow and directly creates users via bulkCreate, accepting arbitrary admin and builder role assignments from the request body. A builder-level user can create a new global admin account and receive the generated password in the response, achieving full privilege escalation.

Details

The vulnerability stems from a mismatch between the authorization level of the onboardUsers endpoint and the user-creation capabilities it exposes when SMTP is not configured.

Route definition (packages/worker/src/api/routes/global/users.ts:93-109):

builderOrAdminRoutes  // <-- allows builders, not just admins
  .post(
    "/api/global/users/onboard",
    buildInviteMultipleValidation(),
    controller.onboardUsers
  )

Compare with the invite and inviteMultiple endpoints which are correctly admin-only:

adminRoutes  // <-- admin only
  .post("/api/global/users/invite", buildInviteValidation(), controller.invite)
  .post("/api/global/users/multi/invite", buildInviteMultipleValidation(), controller.inviteMultiple)

Controller (packages/worker/src/api/controllers/global/users.ts:601-630):

export const onboardUsers = async (ctx) => {
  if (await isEmailConfigured()) {
    await inviteMultiple(ctx)  // admin-only path (delegates to invite flow)
    return
  }

  // No SMTP → directly create users with attacker-controlled roles
  const users = ctx.request.body.map(invite => {
    const password = generatePassword(12)
    createdPasswords[invite.email] = password
    return {
      email: invite.email,
      password,
      forceResetPassword: true,
      roles: invite.userInfo.apps || {},
      admin: { global: !!invite.userInfo.admin },  // <-- attacker-controlled
      builder: invite.userInfo.builder,              // <-- attacker-controlled
      tenantId: tenancy.getTenantId(),
    }
  })

  let resp = await userSdk.db.bulkCreate(users)
  for (const user of resp.successful) {
    user.password = createdPasswords[user.email]  // <-- password returned!
  }
  ctx.body = { ...resp, created: true }
}

Middleware pass-through (packages/backend-core/src/middleware/workspaceBuilderOrAdmin.ts:10-26):

In the worker context (env.isWorker() is true), when there is no workspaceId parameter in the request (which there isn't for the onboard endpoint), the middleware at line 19 checks !workspaceId && env.isWorker() — this is true, so it falls through to line 21 which only checks hasBuilderPermissions. Any global builder passes.

Validation gap (buildInviteMultipleValidation at line 37-45): The Joi schema validates userInfo as Joi.object().optional() with no constraints on its contents, so admin and builder fields pass through.

No downstream check: bulkCreate and buildUser do not strip or validate admin/builder fields — they are written directly to the user document in CouchDB.

PoC

Prerequisites: A self-hosted Budibase instance (default: no SMTP configured) and a user account with builder-level access.

Step 1: Authenticate as a builder user and obtain the session cookie:

# Login as builder
curl -s -c cookies.txt -X POST 'http://localhost:10000/api/global/auth/default/login' \
  -H 'Content-Type: application/json' \
  -d '{"username":"[email protected]","password":"builderpassword"}'

Step 2: Create a new global admin user via the onboard endpoint:

curl -s -X POST 'http://localhost:10000/api/global/users/onboard' \
  -H 'Content-Type: application/json' \
  -b cookies.txt \
  -d '[{"email":"[email protected]","userInfo":{"admin":{"global":true}}}]'

Expected response (includes the…

Record
GHSA-c54j-xp92-wh28
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@budibase/worker
npm
before 3.38.1
3.38.1

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-45716 is a high vulnerability (CVSS 8.8) in Budibase, published May 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.26%, the 17th percentile. Fixed in @budibase/worker 3.38.1.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open