Skip to main content

EUVDEUVD-2026-21494

| CVE-2026-40103 MEDIUM
Incorrect Authorization (CWE-863)
2026-04-10 https://github.com/go-vikunja/vikunja GHSA-v479-vf79-mg83
4.3
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
4.3 MEDIUM
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
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
Low
Availability
None

Lifecycle Timeline

4
EUVD ID Assigned
Apr 10, 2026 - 16:00 euvd
EUVD-2026-21494
Analysis Generated
Apr 10, 2026 - 16:00 vuln.today
Patch released
Apr 10, 2026 - 16:00 nvd
Patch available
CVE Published
Apr 10, 2026 - 15:36 nvd
MEDIUM 4.3

DescriptionGitHub 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.go
  • pkg/routes/routes.go
  • pkg/modules/background/handler/background.go

Route registration exposes separate permissions for the same path:

  • GET /api/v1/projects/:project/background -> projects.background
  • DELETE /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

  1. Log in as a user who can update a project that already has a background.
  2. Create an API token with only:

{"projects":["background"]}

  1. Send:

DELETE /api/v1/projects/<project_id>/background Authorization: Bearer <token>

  1. Observe that the request succeeds and the project background is removed.

For comparison:

  1. Create an API token with only:

{"projects":["background_delete"]}

  1. Repeat the same DELETE request.
  2. Observe that the request is rejected with 401 Unauthorized.

I confirmed this locally with three validations:

  1. /api/v1/routes advertises both background and background_delete.
  2. The matcher unit test proves CanDoAPIRoute() accepts DELETE for background.
  3. The webtest proves a real API token with only background successfully 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.

Share

EUVD-2026-21494 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy