BTC
ETH
SOL
BNB
GOLD
XRP
DOGE
ADA
Back to home
Security

[MEDIUM] Security Advisory: Vikunja: Scoped API tokens with projects.background permission can delete project backgrounds (code.vikunja.io/api)

Vikunja, an open-source, self-hosted task management tool similar to Todoist, ships with a flaw in its scoped API token enforcement.

Vikunja, an open-source, self-hosted task management tool similar to Todoist, ships with a flaw in its scoped API token enforcement. Tokens granted only the projects.background permission—intended for reading project backgrounds—can delete them via the DELETE endpoint. Tokens with the specific projects.background_delete permission get rejected with a 401. This is an authorization bypass affecting automation scripts and integrations that rely on narrowly scoped tokens.

The issue stems from method-confused permission checks in the API routes. I verified it on commit c5450fb55f5192508638cbb3a6956438452a712e from Vikunja’s repo at code.vikunja.io/api. The routes register distinct permissions:

But the enforcement function CanDoAPIRoute() in pkg/models/api_routes.go reconstructs permissions from path segments alone, ignoring the HTTP method. For DELETE requests, it falls back to the parent projects.background, letting mismatched tokens through. The delete handler in pkg/modules/background/handler/background.go then runs unchecked: it verifies project update rights (which the token holder has indirectly), deletes the background file, and clears the BackgroundFileID on the project.

Proof of Concept

Reproduce it like this:

  1. Log in as a user with update rights on a project that has a custom background.
  2. Create a scoped API token with {"projects":["background"]}.
  3. Send the DELETE request:
    curl -X DELETE \
      -H "Authorization: Bearer <your-token>" \
      "https://your-vikunja/api/v1/projects/<project-id>/background"
    

    The background deletes successfully.

Compare with a token scoped to {"projects":["background_delete"]}: the same request fails with 401 Unauthorized. Three checks confirm the bug:

  1. The /api/v1/routes endpoint lists both permissions distinctly.
  2. Unit tests in the matcher show CanDoAPIRoute() greenlights DELETE under background.
  3. End-to-end web tests prove real deletion with the weak token.

Why This Matters

Vikunja targets privacy-focused users who self-host to avoid SaaS data leaks—over 10,000 stars on GitHub, active since 2019. Scoped tokens let you grant minimal access for bots, CI/CD pipelines, or mobile apps without full user creds. This bug breaks that model: a read-only background token becomes destructive.

Attack requires a valid token from a project updater, so no zero-days from public endpoints. But implications hit real workflows. Say you script a dashboard to pull project visuals: one bad cron job wipes backgrounds across teams. Or third-party tools with narrow scopes escalate silently. In multi-user setups, shared tokens amplify risk—least privilege crumbles.

CVEs aren’t assigned yet, rated medium by the advisory, fair given no RCE or mass compromise. Still, self-hosters should audit tokens now. Patch lands in recent releases; check changelog post-commit. Run /api/v1/routes to inspect your setup. Broader lesson: API auth loves shortcuts like path-only matching, but HTTP methods matter. Tools like Vikunja prove even mature open-source code (v0.22+ era) slips on edge cases.

Fix it by regenerating tokens with full scopes or upgrading. Test your own APIs: do permission checkers respect methods? In crypto/security circles, we see this pattern in wallet APIs or DeFi dashboards—over-permissive tokens lead to drains. Vikunja users, rotate those background tokens today.

April 10, 2026 · 3 min · 8 views · Source: GitHub Security

Related