# Vikunja: OIDC email-fallback account linking ignores email_verified, enabling local-account takeover

Vikunja's OIDC emailfallback links SSO logins to local accounts by email alone, ignoring email_verified, letting an attacker with a spoofable issuer claim take over any local account.

- Payout: Research
- Severity: high
- Program: Vikunja
- Found by: maskop9, evilgensec
- Disclosed: 2026-10-09
- CVE: CVE-2026-62367
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-xv7q-fvmc-jx96
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-xv7q-fvmc-jx96
- Tags: area:web domain:web impact:ato kind:research platform:ghsa sev:high tech:go tech:oidc technique:incomplete-fix technique:source-review vuln:access-control vuln:account-takeover vuln:auth-bypass

**Target:** OIDC callback / account-linking logic in pkg/modules/auth/openid/openid.go
**Root cause:** fallbackSearchUsers adds an email-only lookup against issuer='local' accounts and getOrCreateUser mints a session without ever checking the email_verified (or xms_edov) claim, so any token bearing the victim's email links to their local account.
**Steps:**
1. Enable per-provider OIDC `emailfallback: true` (default false).
2. Configure an issuer where the attacker can set an arbitrary unverified email (self-service IdP, mixed federation, or multi-tenant Entra `/common`).
3. Attacker registers at the IdP with the victim's email and logs in via OIDC; `sub` misses, so `fallbackSearchUsers` appends `&user.User{Issuer: user.IssuerLocal, Email: cl.Email}`.
4. `getUser` runs `WHERE issuer='local' AND email=?`, matching the victim's local account; `getOrCreateUser` returns it and a full session is minted without a password check.
**How found:** Code review of the OIDC flow: noticed identity resolves on (issuer, subject) first, then the emailfallback branch adds an email-only search against IssuerLocal; grepped for email_verified/xms_edov and found nothing, and saw the code's own warning at openid.go:388 that was never enforced.
**Exploitation:** Attacker obtains an IdP token asserting the victim's email (no verification required), completes the unauthenticated OIDC callback, and is logged in as the victim's local account with full read/write/delete over projects, tasks, attachments and shares. Repeatable; no victim interaction.
**Escalation:** Repeatable against any local account whose email the attacker can assert; TOTP users blocked by the 2.3.0 enforceTOTPIfRequired gate, non-TOTP users fully exposed.
**Insight:** When an SSO path falls back to matching on a mutable claim like email, check whether the code ever reads email_verified/xms_edov — a comment warning about untrusted providers is a strong signal the check is missing; also note the 2.3.0 fix added TOTP gating rather than claim verification, leaving non-TOTP users exposed.

