CVE-2026-91972: Vikunja before 2.6.0 Authentication Bypass via Unthrottled API

Published Sep 15, 2026
·
Updated

Summary registerAPIRoutesV2 never applies the unconditional pre-auth rate-limit floor (unauthRateLimit()) to the v2 public routes — it passes that limiter only to /api/v2/ws — and otherwise relies on setupRateLimit, which registers nothing when ratelimit.enabled is false (the default). So on a stock install every v2 pre-auth endpoint (login, register, password-reset token, oauth token) is unthrottled, while its v1 twin is throttled.

Details unauthRateLimit() -> perMinuteIPRateLimit("noauth", RateLimitNoAuthRoutesLimit) (pkg/routes/ratelimit.go, ~lines 100-118) is an unconditional per-IP floor (default 10/60s) that deliberately ignores RateLimitEnabled, which is why v1's pre-auth routes are throttled even with the global limiter off. v1 applies it: ur := a.Group(""); ur.Use(unauthRateLimit()) (pkg/routes/routes.go ~line 459). registerAPIRoutesV2 (~lines 405-431) passes the unauthRateLimit() instance only to /api/v2/ws; its auth routes get only setupRateLimit(a, ...), which is config-gated and registers nothing by default.

PoC (verified at runtime against v2.5.0) POST /api/v1/login x25 -> 429 from attempt 5 POST /api/v2/login x25 -> 403 x25, 429 x0 POST /api/v1/user/password/token -> 429 (throttled) POST /api/v2/user/password/token x20 -> 404 x20, 429 x0 Request bodies are byte-identical across versions (shared user.Login / user.PasswordTokenRequest). Both v2 endpoints reach their handlers (403/404, not route-404), so the comparison is valid.

Impact The pre-auth rate-limit floor — the instance's only default anti-brute-force / anti-abuse control — is absent on all v2 public endpoints. Enables unbounded credential guessing, account-enumeration probing, and password-reset flooding on a default install. Reported as an authentication-control bypass, not a DoS.

Fix Apply unauthRateLimit() to the v2 public route group, matching v1.

Other sources

Vikunja versions before 2.6.0 fail to apply rate limiting to /api/v2 public authentication endpoints including login, register, password-reset, and OAuth token routes. Remote unauthenticated attackers can perform unbounded credential guessing, account enumeration, and password-reset flooding attacks without throttling restrictions.

— MITRE

Affected Software

2 affected componentsFixes available
Vikunja Vikunja<2.6.0
go/code.vikunja.io/api<=2.5.0
2.6.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade go/code.vikunja.io/api to a version that resolves this vulnerability.

    Fixed in 2.6.0
  2. Upgrade

    Upgrade Vikunja to a version that resolves this vulnerability.

    Fixed in 2.6.0

Event History

Sep 15, 2026
CVE Published
via MITRE·03:18 PM
Data Sourced
via MITRE·03:18 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·04:17 PM
DescriptionSeverityWeakness
Oct 9, 2026
Advisory Published
via GitHub·08:51 PM
Data Sourced
via GitHub·08:51 PM
DescriptionWeaknessAffected Software

Frequently Asked Questions

1

Which deployments are affected?

Vikunja versions before 2.6.0 are affected if they expose the /api/v2 public authentication endpoints, including login, registration, password-reset, or OAuth token routes.

2

What does an attacker need to exploit this issue?

An attacker only needs network access to the affected public API endpoints. No account, credentials, or user interaction is required.

3

What attacks become practical without rate limiting?

An attacker can make unlimited credential-guessing attempts, enumerate accounts, or flood password-reset functionality because the affected routes are not throttled.

4

What should be done if an immediate upgrade is not possible?

The provided information identifies the missing control as rate limiting on public /api/v2 authentication routes. Apply throttling protections to the login, registration, password-reset, and OAuth token endpoints until upgrading to 2.6.0 or later.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203