GHSA-gh4h-34gr-87r7: Budibase: OAuth2 Token Disclosure via Automation Test Results Broadcast to Other Builders
Summary
When an SSO-authenticated user tests an automation in the Budibase builder, their OAuth2 access token and refresh token are included in the automation test results. These results are broadcast via WebSocket to all builders connected to the same dev app and stored in an in-memory cache accessible to any builder who polls the test status endpoint. This allows any co-builder of the same app to steal the testing user's OAuth2 tokens.
Details
The vulnerability exists because getUserContextBindings() intentionally includes OAuth2 tokens in user context bindings (so automations can call external APIs), but the automation test pipeline exposes the full result — including these tokens — to all builders of the same app without sanitization.
Step 1: Tokens included in user bindings
In packages/server/src/sdk/users/utils.ts:134-161:
export function getUserContextBindings(user: ContextUser): UserBindings {
const bindings: UserBindings = {
_id: user._id,
email: user.email,
// ...
}
if (isSSOUser(user) && user.oauth2) {
bindings.oauth2 = {
accessToken: user.oauth2.accessToken, // <-- sensitive
refreshToken: user.oauth2.refreshToken, // <-- sensitive
}
}
return bindings
}
Step 2: Bindings passed to automation execution
In packages/server/src/api/controllers/automation.ts:311-312:
const user = sdk.users.getUserContextBindings(ctx.user)
return await triggers.externalTrigger(
{ ...automation, disabled: false },
{ ...input, appId, user }, // user with tokens passed as event param
{ getResponses: true, onProgress: emitProgress }
)
Step 3: Tokens placed in trigger outputs
In packages/server/src/threads/automation.ts:409-413:
const trigger: AutomationTriggerResult = {
id: data.automation.definition.trigger.id,
stepId: data.automation.definition.trigger.stepId,
inputs: null,
outputs: data.event, // data.event includes user.oauth2 tokens
}
Step 4: Result broadcast without sanitization
The full result (including trigger.outputs.user.oauth2) is exposed via two vectors:
Details
Original advisory: https://github.com/advisories/GHSA-gh4h-34gr-87r7
More from GitHub Security Advisories
- mediumGHSA-jr6p-8pjj-mfx6: Capsule has an incomplete fix of CVE-2026-22872: TenantResource RawItems and Generators s…2026-07-31
- mediumGHSA-68cj-mvg9-rgm2: Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing…2026-07-31
- mediumGHSA-ff84-5f28-78qj: re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex`…2026-07-31
- mediumGHSA-6hxr-mr5r-9836: re2: Global `String.prototype.match` with an empty-matchable pattern never advances → inf…2026-07-31
- mediumGHSA-x83g-979r-f5fh: Sylius Mollie Plugin has unauthenticated IDOR that leaks order token and customer PII2026-07-31