Vikunja’s Improper Access Control Enables Bypass of Administrator-Imposed Account Disablement
Date: 2026-03
Affected: go/code.vikunja.io/api
Attack vector: auth-bypass
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-29794
CVE-2026-33315
CVE-2026-33316
CWE: CWE-284
CWE-288
CWE-807
CWE-862
CWE-863
CVSS: 8.1 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N)

### Summary A flaw in Vikunja’s password reset logic allows disabled users to regain access to their accounts. The `ResetPassword()` function sets the user’s status to `StatusActive` after a successful password reset without verifying whether the account was previously disabled. By requesting a reset token through `/api/v1/user/password/token` and completing the reset via `/api/v1/user/password/reset`, a disabled user can reactivate their account and bypass administrator-imposed account disablement. #### Vulnerable Code Snippet In `pkg/user/user_password_reset.go`, beginning at line 66: ```go // Hash the password user.Password, err = HashPassword(reset.NewPassword) if err != nil { return } err = removeTokens(s, user, TokenPasswordReset) if err != nil { return } user.Status = StatusActive // <--- VULNERABILITY: Unconditionally sets status to Active _, err = s. Cols("password", "status"). Where("id = ?", user.ID). Update(user) if err != nil { return } ``` The code is vulnerable because it assumes that any user resetting their password is transitioning from a normal state or an "Email Confirmation Required" state into an "Active" state. It completely ignores whether the user was placed in the `StatusDisabled` state by an administrator. Additionally, in the token request function (`RequestUserPasswordResetTokenByEmail`), the system fetches the user via `GetUserWithEmail()` which does **not** filter out disabled users, allowing them to legally request


Mitigations:

Architectural layers (MAESTRO):