Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Primary rating from GitHub Advisory · only source for this CVE.
CVSS VectorGitHub Advisory
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Lifecycle Timeline
4DescriptionGitHub Advisory
Summary
Vikunja's scoped API token enforcement for custom project background routes is method-confused. A token with only projects.background can successfully delete a project background, while a token with only projects.background_delete is rejected.
This is a scoped-token authorization bypass.
Details
I verified this locally on commit c5450fb55f5192508638cbb3a6956438452a712e.
Relevant code paths:
pkg/models/api_routes.gopkg/routes/routes.gopkg/modules/background/handler/background.go
Route registration exposes separate permissions for the same path:
GET /api/v1/projects/:project/background->projects.backgroundDELETE /api/v1/projects/:project/background->projects.background_delete
At enforcement time, CanDoAPIRoute() falls back to the parent group and reconstructs the child permission from the path segments only. For the DELETE request, that becomes background, so the matcher accepts any token containing projects.background without re-checking the HTTP method or matching the stored route detail.
This matters because RemoveProjectBackground() is a real destructive operation:
- It checks project update rights.
- It deletes the background file if present.
- It clears the project's
BackgroundFileID.
PoC
- Log in as a user who can update a project that already has a background.
- Create an API token with only:
{"projects":["background"]}
- Send:
DELETE /api/v1/projects/<project_id>/background Authorization: Bearer <token>
- Observe that the request succeeds and the project background is removed.
For comparison:
- Create an API token with only:
{"projects":["background_delete"]}
- Repeat the same DELETE request.
- Observe that the request is rejected with
401 Unauthorized.
I confirmed this locally with three validations:
/api/v1/routesadvertises bothbackgroundandbackground_delete.- The matcher unit test proves
CanDoAPIRoute()accepts DELETE forbackground. - The webtest proves a real API token with only
backgroundsuccessfully deletes the background.
Impact
Scoped API tokens can exceed their intended capability. A token intended for project background access can delete project backgrounds, which weakens the trust model for automation and third-party integrations that rely on narrowly scoped tokens.
The attacker needs a valid API token created by a user who has update rights on the target project, but the token itself only needs the weaker projects.background permission.
AnalysisAI
Vikunja's scoped API token enforcement for project background routes contains a method-confusion authorization bypass allowing tokens with only projects.background permission to delete project backgrounds despite lacking the projects.background_delete permission. This enables authenticated attackers to perform unintended destructive operations on projects they have update access to, weakening the permission model for narrowly scoped API tokens used in automation and third-party integrations. The vulnerability has a vendor-released patch available and is confirmed reproducible on the affected codebase.
Technical ContextAI
Vikunja implements scoped API token enforcement through a permission matching system in pkg/models/api_routes.go and pkg/routes/routes.go. The DELETE request to /api/v1/projects/:project/background should require the projects.background_delete permission, while GET requests require projects.background. However, the CanDoAPIRoute() function performs fallback logic that reconstructs child permissions from path segments alone, ignoring the HTTP method. For DELETE requests to the background endpoint, this reconstruction yields background instead of background_delete, causing the permission matcher to accept any token containing projects.background without validating the HTTP method or the stored route-specific permission requirements. The affected CPE is pkg:go/code.vikunja.io_api, a Go-based project management platform. The root cause is classified under CWE-863 (Incorrect Authorization), reflecting inadequate method-aware permission checking in the token validation logic.
RemediationAI
Upgrade Vikunja to version 2.3.0 or later, which contains the upstream fix implemented in commit 6a0f39b252a81fa4b19dc56dc889183acc9225ae (merged via pull request #2584). No workarounds are available for earlier versions; the permission matching logic must be corrected to properly enforce method-specific scopes during token validation. Users unable to immediately upgrade should audit existing scoped API tokens to ensure they follow the principle of least privilege and should monitor API logs for unauthorized DELETE requests to project background endpoints. Additional details and the official advisory are available at https://github.com/go-vikunja/vikunja/security/advisories/GHSA-v479-vf79-mg83.
Same weakness CWE-863 – Incorrect Authorization
View allSame technique Authentication Bypass
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-21494
GHSA-v479-vf79-mg83