Disclosure summary
### Summary Once a user has TOTP enabled, the API still hands back the raw shared secret to anyone holding that account's access token. Reading it doesn't ask for the password, even though disabling TOTP does. So a stolen token, an XSS, or a browser left open is enough to copy the second factor into your own authenticator and keep generating valid codes indefinitely. ### Details `GET /api/v1/user/settings/totp` returns the full TOTP object, including the secret field and the otpauth:// provisioning URL. `GET /api/v1/user/settings/totp/qrcode` renders the same secret as a QR image. Neither requires re-authentication, the access token alone is enough. This is inconsistent with the rest of the flow: `POST /api/v1/user/settings/totp/disable` calls CheckUserPassword before it will turn TOTP off. So the destructive action is gated behind the password, but reading out the secret that backs the second factor isn't. There's also no reason for the secret to be readable at all once enrollment is finished, the client only needs it during setup. The fix is to stop returning secret/url/the QR code once enabled is true (only expose them during the enrollment window). Requiring the password on the
Source-specific records & product guidance
Sources retain their own attribution and scoring. Follow the original record to confirm affected versions, fixed releases, and configuration conditions.
GitHub Reviewed Security Advisories · GHSA-88f6-4rjv-x774
Open original source · Updated Oct 09, 2026
Vikunja: TOTP secret is readable after enrollment, no step-up auth
Source severity: MEDIUM / 5.3
| Ecosystem | Package | Affected range | First patched |
|---|---|---|---|
| go | code.vikunja.io/api | 2.6.0 |
Original records & references
- NIST NVD record
- CVE Program record
- github.com — Reviewed advisory
PUBLISHED 2026-10-09T16:51:17-04:00
MODIFIED 2026-10-09T16:51:19-04:00
INGESTED 2026-10-10T20:45:43-04:00