Server: Budibase: OIDC SSO account takeover: incoming identity linked by email without checking email_verified (CVE-2026-73302)
### Summary Budibase's OIDC SSO login links an incoming SSO identity to an existing Budibase account **by email address alone**, without ever checking the `email_verified` claim of the OIDC ID token. Budibase first tries to match the IdP `sub`; when that misses (any fresh attacker IdP account) it silently falls back to matching by the `email` claim and **merges into the existing account by email**, preserving that account's `_id` and roles. Because the `email_verified` flag is never read, an attacker who can make a **configured/trusted** IdP emit a token carrying `email = <victim>` with `email_verified = false` is logged into Budibase **as the victim**, inheriting the victim's roles (including global admin/builder). Per OIDC Core §5.7 the `email` claim MUST NOT be used as an identity key unless `email_verified` is `true`; Budibase effectively delegates all account-linking trust to every configured IdP's email-verification policy while checking nothing itself. Full account takeover of any existing Budibase user, including the instance owner. ### Details The OIDC verify callback extracts the email and never consults `email_verified`: - `packages/backend-core/src/middleware/passport/sso/oidc.ts:59` — `email: getEmail(profile, jwtClaims)`. - `getEmail` (`oidc.ts:113-135`) returns `profile._json.email` ->`jwtClaims.email` -> `preferred_username`. **No `email_verified` check.** - `buildJwtClaims` (`oidc.ts:99-107`) assembles claims from `_json.email`/`emails[0].value` — no verification flag is read. `grep -r email_verified packages/` -> 0 hits. The email is then used as the **account-linking key**: - `sso.authenticate(...)` -> `packages/backend-core/src/middleware/passport/sso/sso.ts`: - `:38,44` `users.getById(generateGlobalUserID(details.userId))` keyed on the IdP `sub`; for a fresh attacker IdP account this 404s and is swallowed (`:45-54`). - `:57-59` **fallback:** `dbUser = await users.getGlobalUserByEmail(details.email)` -> loads the **victim's** account (victim `_id` + roles) purely by email (`packages/backend-core/src/users/users.ts:100-124`, `USER_BY_EMAIL` view, no binding to the IdP `sub`). - `syncUser(...)` (`sso.ts:80,102-138`) spreads `...user`, preserving the victim `_id`/`tenantId`/`roles`; only overwrites provider fields. - `UserDB.save` (`packages/backend-core/src/users/db.ts:235`): because `ssoUser._id` is the victim's, the `_id` branch runs (`:253`), `getById(_id)` matches the victim (`:256`), the "Email address cannot be changed" guard (`:257-259`) does not fire (`dbUser.email === email`), and the `EmailUnavailableError` guard (`:269-275`) is skipped (it only runs in the `!dbUser` branch). The merge proceeds silently; a session JWT is issued for the victim. Per OIDC Core §5.7, the `email` claim MUST NOT be used as an identity key unless `email_verified` is `true`. Budibase never reads the flag. **Preconditions (attack requirement — `AT:P`):** the attacker must be able to authenticate through an IdP that the Budibase instance **trusts** AND get that IdP to assert the victim's email with `email_verified = false`. This is reachable, not exotic: - **Self-registration with an unverified email — Keycloak and Authentik ship with *"Verify Email" OFF by default*; if the trusted IdP allows public sign-up, the attacker registers a new account and simply enters `email = <victim>` at sign-up. No confirmation email is needed — the IdP stores and asserts it unverified.** - **Self-service profile editing** — many IdPs let a logged-in user change their own email without forced re-verification. - **Attacker-operated / federated IdP or permissive social login** — where the attacker controls or influences a trusted provider, or the provider asserts a user-typed (unverified) email. It is **not** exploitable through a strict corporate IdP that enforces email verification (there `email_verified = true` and the attacker cannot claim the victim's address) — which is exactly why Budibase must check the flag rather than assume every configured IdP enforces it. The defect is unconditional on the Budibase side; the attack requirement is purely the (default, common) IdP email policy. ### PoC Reproduced live on Budibase `3.39.14` (self-hosted, community license) against a stock **Keycloak 26** realm `budi` with default "Verify Email" = off; OIDC client registered and activated in Budibase. **Setup:** a pre-existing **victim** global-admin Budibase account `[email protected]` (`_id = us_1ab2dfcf…`, local account, *no IdP link*). The attacker owns their **own** IdP account (`attacker`, distinct `sub`) and can set its email attribute unverified. **Step 1 — the IdP asserts the claim (proves `email_verified=false`):** ``` POST /realms/budi/protocol/openid-connect/token (Keycloak) grant_type=password&client_id=budibase&client_secret=…&username=attacker&password=Attacker123!&scope=openid email profile -> id_token payload: { "sub":"3cf58c45-…", "preferred_username":"attacker", "email":"victim@s
AI Analysis
Technical Summary
Budibase's OIDC Single Sign-On (SSO) login process attempts to match incoming identities first by the IdP subject (sub) claim, and if no match is found, falls back to matching by the email claim without checking the email_verified flag. Because Budibase never verifies whether the email is confirmed (email_verified=true), an attacker who can authenticate through a trusted IdP and have it assert the victim's email with email_verified=false can gain access to the victim's Budibase account. The attacker inherits the victim's user ID and roles, including global admin privileges. This violates OIDC Core specification §5.7, which mandates that the email claim must only be used as an identity key if email_verified is true. The vulnerability requires the attacker to authenticate via a trusted IdP that allows unverified email assertions, such as Keycloak or Authentik with default settings that disable email verification. Budibase versions up to and including 3.38.1 are affected. No patch information is provided in the advisory.
Potential Impact
An attacker who can authenticate through a trusted IdP and have it assert the victim's email with email_verified=false can fully take over the victim's Budibase account. This includes inheriting all roles and permissions, such as global admin or builder roles. The attacker can thus gain unauthorized administrative control over the Budibase instance, leading to complete compromise of the affected user accounts. The vulnerability undermines the trust model of OIDC SSO by ignoring the email verification status, allowing account takeover via unverified email assertions.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, administrators should ensure that all configured IdPs enforce strict email verification policies (email_verified=true) before asserting email claims. Avoid trusting IdPs that allow unverified email assertions or permit self-registration without email verification. Consider disabling or restricting OIDC SSO login from IdPs with permissive email verification settings. Monitor vendor communications for updates and patches addressing this issue.
Server: Budibase: OIDC SSO account takeover: incoming identity linked by email without checking email_verified (CVE-2026-73302)
Description
### Summary Budibase's OIDC SSO login links an incoming SSO identity to an existing Budibase account **by email address alone**, without ever checking the `email_verified` claim of the OIDC ID token. Budibase first tries to match the IdP `sub`; when that misses (any fresh attacker IdP account) it silently falls back to matching by the `email` claim and **merges into the existing account by email**, preserving that account's `_id` and roles. Because the `email_verified` flag is never read, an attacker who can make a **configured/trusted** IdP emit a token carrying `email = <victim>` with `email_verified = false` is logged into Budibase **as the victim**, inheriting the victim's roles (including global admin/builder). Per OIDC Core §5.7 the `email` claim MUST NOT be used as an identity key unless `email_verified` is `true`; Budibase effectively delegates all account-linking trust to every configured IdP's email-verification policy while checking nothing itself. Full account takeover of any existing Budibase user, including the instance owner. ### Details The OIDC verify callback extracts the email and never consults `email_verified`: - `packages/backend-core/src/middleware/passport/sso/oidc.ts:59` — `email: getEmail(profile, jwtClaims)`. - `getEmail` (`oidc.ts:113-135`) returns `profile._json.email` ->`jwtClaims.email` -> `preferred_username`. **No `email_verified` check.** - `buildJwtClaims` (`oidc.ts:99-107`) assembles claims from `_json.email`/`emails[0].value` — no verification flag is read. `grep -r email_verified packages/` -> 0 hits. The email is then used as the **account-linking key**: - `sso.authenticate(...)` -> `packages/backend-core/src/middleware/passport/sso/sso.ts`: - `:38,44` `users.getById(generateGlobalUserID(details.userId))` keyed on the IdP `sub`; for a fresh attacker IdP account this 404s and is swallowed (`:45-54`). - `:57-59` **fallback:** `dbUser = await users.getGlobalUserByEmail(details.email)` -> loads the **victim's** account (victim `_id` + roles) purely by email (`packages/backend-core/src/users/users.ts:100-124`, `USER_BY_EMAIL` view, no binding to the IdP `sub`). - `syncUser(...)` (`sso.ts:80,102-138`) spreads `...user`, preserving the victim `_id`/`tenantId`/`roles`; only overwrites provider fields. - `UserDB.save` (`packages/backend-core/src/users/db.ts:235`): because `ssoUser._id` is the victim's, the `_id` branch runs (`:253`), `getById(_id)` matches the victim (`:256`), the "Email address cannot be changed" guard (`:257-259`) does not fire (`dbUser.email === email`), and the `EmailUnavailableError` guard (`:269-275`) is skipped (it only runs in the `!dbUser` branch). The merge proceeds silently; a session JWT is issued for the victim. Per OIDC Core §5.7, the `email` claim MUST NOT be used as an identity key unless `email_verified` is `true`. Budibase never reads the flag. **Preconditions (attack requirement — `AT:P`):** the attacker must be able to authenticate through an IdP that the Budibase instance **trusts** AND get that IdP to assert the victim's email with `email_verified = false`. This is reachable, not exotic: - **Self-registration with an unverified email — Keycloak and Authentik ship with *"Verify Email" OFF by default*; if the trusted IdP allows public sign-up, the attacker registers a new account and simply enters `email = <victim>` at sign-up. No confirmation email is needed — the IdP stores and asserts it unverified.** - **Self-service profile editing** — many IdPs let a logged-in user change their own email without forced re-verification. - **Attacker-operated / federated IdP or permissive social login** — where the attacker controls or influences a trusted provider, or the provider asserts a user-typed (unverified) email. It is **not** exploitable through a strict corporate IdP that enforces email verification (there `email_verified = true` and the attacker cannot claim the victim's address) — which is exactly why Budibase must check the flag rather than assume every configured IdP enforces it. The defect is unconditional on the Budibase side; the attack requirement is purely the (default, common) IdP email policy. ### PoC Reproduced live on Budibase `3.39.14` (self-hosted, community license) against a stock **Keycloak 26** realm `budi` with default "Verify Email" = off; OIDC client registered and activated in Budibase. **Setup:** a pre-existing **victim** global-admin Budibase account `[email protected]` (`_id = us_1ab2dfcf…`, local account, *no IdP link*). The attacker owns their **own** IdP account (`attacker`, distinct `sub`) and can set its email attribute unverified. **Step 1 — the IdP asserts the claim (proves `email_verified=false`):** ``` POST /realms/budi/protocol/openid-connect/token (Keycloak) grant_type=password&client_id=budibase&client_secret=…&username=attacker&password=Attacker123!&scope=openid email profile -> id_token payload: { "sub":"3cf58c45-…", "preferred_username":"attacker", "email":"victim@s
CVSS v4.0
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
Budibase's OIDC Single Sign-On (SSO) login process attempts to match incoming identities first by the IdP subject (sub) claim, and if no match is found, falls back to matching by the email claim without checking the email_verified flag. Because Budibase never verifies whether the email is confirmed (email_verified=true), an attacker who can authenticate through a trusted IdP and have it assert the victim's email with email_verified=false can gain access to the victim's Budibase account. The attacker inherits the victim's user ID and roles, including global admin privileges. This violates OIDC Core specification §5.7, which mandates that the email claim must only be used as an identity key if email_verified is true. The vulnerability requires the attacker to authenticate via a trusted IdP that allows unverified email assertions, such as Keycloak or Authentik with default settings that disable email verification. Budibase versions up to and including 3.38.1 are affected. No patch information is provided in the advisory.
Potential Impact
An attacker who can authenticate through a trusted IdP and have it assert the victim's email with email_verified=false can fully take over the victim's Budibase account. This includes inheriting all roles and permissions, such as global admin or builder roles. The attacker can thus gain unauthorized administrative control over the Budibase instance, leading to complete compromise of the affected user accounts. The vulnerability undermines the trust model of OIDC SSO by ignoring the email verification status, allowing account takeover via unverified email assertions.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, administrators should ensure that all configured IdPs enforce strict email verification policies (email_verified=true) before asserting email claims. Avoid trusting IdPs that allow unverified email assertions or permit self-registration without email verification. Consider disabling or restricting OIDC SSO login from IdPs with permissive email verification settings. Monitor vendor communications for updates and patches addressing this issue.
Technical Details
- Gcve Source
- db.gcve.eu
- Osv Id
- GHSA-hp6v-6jw7-gv2f
- Osv Schema Version
- 1.4.0
- Aliases
- []
- Ecosystems
- ["npm"]
- Database Specific Severity
- CRITICAL
- Cvss Version
- 4.0
Threat ID: 6a65422e9c2644c7f808a601
Added to database: 07/25/2026, 23:09:34 UTC
Last enriched: 07/25/2026, 23:57:06 UTC
Last updated: 09/07/2026, 20:43:04 UTC
Views: 154
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.