Skip to content

← Public intelligence

Go package

code.vikunja.io/api

Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.

Open advisories

53 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.

  1. High, CVSS 8.1GoAmendedPublished

    Vikunja: Scoped API token can mint unrestricted OAuth session credentials

    CVE-2026-57458 · GHSA-v3p6-34mc-hj7v

    Affected
    • Go code.vikunja.io/api >= 2.3.0, <= 2.3.0
    Fixed in
    2.4.0· Vendor fix available
    Issue
    A scoped API token can bypass its declared permissions by using the OAuth authorization flow to mint normal session credentials. A token limited to: can call /api/v1/oauth/authorize, receive an OAuth authorization code, exchange it at /api/v1/oauth/token, and obtain a normal bearer JWT plus refresh token. The resulting credentials are not restricted by the original API-token permissions. Affected Component Scoped API tokens OAuth authorization flow POST /api/v1/oauth/authorize POST /api/v1/oauth/token Impact A narrowly scoped API token with only oauth.authorize can be converted into normal session credentials for the same user. This bypasses the intended API-token permission boundary. An attacker who obtains or is delegated such a limited token can mint a normal JWT and refresh token, then access routes outside the original token scope. Runtime validation showed that the original scoped token could not access GET /api/v1/user, but the minted OAuth access token could access:…

    Recommended action: Upgrade to 2.4.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  2. Medium, CVSS 5.0GoAmendedPublished

    Vikunja vulnerable to authenticated cross-tenant kanban-bucket relocation via project_view_id mass-assignment

    CVE-2026-55067 · GHSA-569v-q83c-3j3g

    Affected
    • Go code.vikunja.io/api <= 2.3.0
    Fixed in
    2.4.0· Vendor fix available
    Issue
    POST /api/v1/projects/{project}/views/{view}/buckets/{bucket} mass-assigns the request body's projectviewid onto the bucket row. The permission check only verifies that the URL-supplied bucket already belongs to the URL-supplied (project, view) pair; the body's projectviewid is never validated. Any signed-in user can therefore take one of their own buckets and graft it into any other tenant's kanban view, with attacker-controlled title and the attacker's account as createdby. This vulnerability was found using an LLM, and manually verified against latest (2.3.0). Vulnerable code pkg/models/kanban.go (lines 348-359): Bucket.CanUpdate (canDoBucket) only validates that the URL-supplied {bucket} belongs to the URL-supplied {project}/{view}. The body's projectviewid reaches Update unchecked and is written through. Proof of Concept Prerequisites: Two registered users (attacker and victim). In the IDs below: attacker's project is 2, kanban view 8; victim's project is 1, kanban view…

    Recommended action: Upgrade to 2.4.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  3. High, CVSS 7.1GoAmendedPublished

    Vikunja has cross-tenant IDOR in kanban move-task endpoint via unauthorized body task_id

    CVE-2026-55066 · GHSA-5pg6-m483-7vrg

    Affected
    • Go code.vikunja.io/api <= 2.3.0
    Fixed in
    2.4.0· Vendor fix available
    Issue
    The kanban endpoint POST /api/v1/projects/{project}/views/{view}/buckets/{bucket}/tasks moves a task into a bucket. The task is identified by taskid in the request body. The endpoint's authorization check (TaskBucket.CanUpdate) only verifies that the caller may update the project/view/bucket named in the URL — it never checks any permission on taskid. Any authenticated user can therefore supply another user's task ID (task IDs are a global, sequential integer space) against a kanban bucket in their own project. The server loads that victim task with no authorization check, returns its full contents in the response, and — when the target bucket is a "done" bucket — writes to the victim task's row. This is the same vulnerability class Vikunja has already remediated for task relations (CVE-2026-33676), task attachments (CVE-2026-33678), task comments (CVE-2026-33313) and CalDAV task read (CVE-2026-35598). TaskBucket is the task-child operation that was missed. --- Root cause 1.…

    Recommended action: Upgrade to 2.4.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  4. High, CVSS 8.1GoAmendedPublished

    Vikunja vulnerable to Improper Authorization and Authorization Bypass Through User-Controlled Key

    CVE-2026-55065 · GHSA-gg93-x632-9ccv

    Affected
    • Go code.vikunja.io/api >= 0.24.6, < 2.4.0
    Fixed in
    2.4.0· Vendor fix available
    Issue
    A user with only a single self-owned project can permanently destroy the Kanban bucket assignments (taskbuckets) and task ordering (taskpositions) of any other project view in the entire instance. The ProjectView.Delete model method runs three SQL statements: the first is properly scoped to (viewid, projectid), but the next two cascading deletes on taskbuckets and taskpositions filter only on the URL-supplied projectviewid. The permission check (CanDelete) gates on Admin of the URL :project but never confirms that the URL :view actually belongs to that project. Details ProjectView.Delete (file: pkg/models/projectview.go, line 250) cascades on the bare pv.ID for the second and third deletes, ignoring pv.ProjectID: pv.ID and pv.ProjectID come straight from the URL path via c.Bind — see the param tags on the struct (pkg/models/projectview.go, lines 133–137): The route is registered with both params in pkg/routes/routes.go, line 791: CanDelete (file:…

    Recommended action: Upgrade to 2.4.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  5. Medium, CVSS 4.3GoAmendedPublished

    Vikunja has an incomplete fix for CVE-2026-35595: Write-only user can detach shared project from parent hierarchy via parent_project_id=0

    CVE-2026-55064 · GHSA-44v6-7fxq-vgf4

    Affected
    • Go code.vikunja.io/api >= 2.3.0, < 2.4.0
    Fixed in
    2.4.0· Vendor fix available
    Issue
    The fix for CVE-2026-35595 (project re-parenting privilege escalation) only gates reparent operations when parentprojectid 0. A user with Write (but not Admin) permission on a shared child project can detach it from its parent by sending parentprojectid: 0, bypassing the Admin requirement. This severs the recursive CTE permission inheritance chain, potentially disrupting the project hierarchy and affecting inherited access for other collaborators. Affected component - Package: go-vikunja/vikunja - Affected versions: v2.3.0 and later (including latest unstable v2.3.0-246-9852aff4). The fix for CVE-2026-35595 was introduced in v2.3.0 but left the detach-to-root case unpatched. Fixed in 2.4.0. - Tested on: Vikunja v2.3.0 (Docker image vikunja/vikunja:2.3.0) AND latest unstable (vikunja/vikunja:unstable, v2.3.0-246-9852aff4 built 2026-04-27) Technical detail Vulnerable code File: pkg/models/project.go (lines 1009-1041) File: pkg/models/projectpermissions.go (line 145) File:…

    Recommended action: Upgrade to 2.4.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  6. Medium, CVSS 5.3GoAmendedPublished

    Vikunja has a project duplication bypasses write-permission check on the target parent project

    CVE-2026-54766 · GHSA-f27p-pw2p-9pr4

    Affected
    • Go code.vikunja.io/api >= 0.21.0, <= 2.3.0
    Fixed in
    2.4.0· Vendor fix available
    Issue
    The project-duplication endpoint fails to enforce write access to the target parent project. Any authenticated (non-link-share) user can duplicate a project they can read into any parent project on the instance, regardless of whether they have write access to that parent — injecting an attacker-owned project into another user's or team's project hierarchy. Details ProjectDuplicate.CanCreate (pkg/models/projectduplicate.go) is meant to require write access to the parent the duplicate is placed under — its own comment says "Parent project exists + user has write access". The implementation does neither correctly: Two defects compound here: 1. Wrong permission method. It calls parent.CanCreate ("may I create this project?") instead of parent.CanWrite ("may I create children inside this project?"). The latter is what the normal create path uses — POST /projects with a parentprojectid enforces parent.CanWrite via Project.CanCreate (pkg/models/projectpermissions.go:196-199). 2.…

    Recommended action: Upgrade to 2.4.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  7. Medium, CVSS 5.4GoPublished

    Vikunja: Scoped API tokens with projects.background permission can delete project backgrounds

    CVE-2026-40103 · GHSA-v479-vf79-mg83

    Affected
    • Go code.vikunja.io/api < 2.3.0
    Fixed in
    2.3.0· Vendor fix available
    Issue
    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.backgrounddelete is rejected. This is a scoped-token authorization bypass. Details I verified this locally on commit c5450fb55f5192508638cbb3a6956438452a712e. Relevant code paths: pkg/models/apiroutes.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.backgrounddelete 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…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  8. Medium, CVSS 5.4GoPublished

    Vikunja has File Size Limit Bypass via Vikunja Import

    CVE-2026-35602 · GHSA-qh78-rvg3-cv54

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    The Vikunja file import endpoint uses the attacker-controlled Size field from the JSON metadata inside the import zip instead of the actual decompressed file content length for the file size enforcement check. By setting Size to 0 in the JSON while including large compressed file entries in the zip, an attacker bypasses the configured maximum file size limit. Details During import, the JSON metadata from data.json inside the zip archive is deserialized into project structures. File content is read independently from the zip entries. When creating attachments, the code at pkg/modules/migration/createfromstructure.go:406 passes the attacker-controlled File.Size from the JSON: The file size enforcement check at pkg/files/files.go:118 then evaluates this attacker-controlled value: With Size set to 0 in the JSON, the comparison 0 20MB evaluates to false and the check passes. The actual file content (from the zip entry) can be up to 500MB per entry (the readZipEntry limit). Highly…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  9. Medium, CVSS 4.1GoPublished

    Vikunja has iCalendar Property Injection via CRLF in CalDAV Task Output

    CVE-2026-35601 · GHSA-2g7h-7rqr-9p4r

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    The CalDAV output generator builds iCalendar VTODO entries via raw string concatenation without applying RFC 5545 TEXT value escaping. User-controlled task titles containing CRLF characters break the iCalendar property boundary, allowing injection of arbitrary iCalendar properties such as ATTACH, VALARM, or ORGANIZER. Details The ParseTodos function at pkg/caldav/caldav.go:146 concatenates the task summary directly into the iCalendar output: RFC 5545 Section 3.3.11 requires TEXT property values to escape newlines as \n, semicolons as \;, commas as \,, and backslashes as \\. None of these escaping rules are applied to Summary, Categories, UID, project name, or alarm Description fields. Go's JSON decoder preserves literal CR/LF bytes in string values, so task titles created via the REST API retain CRLF characters. When these tasks are served via CalDAV, the newlines break the SUMMARY property and the subsequent text is parsed by CalDAV clients as independent iCalendar…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  10. Medium, CVSS 5.4GoPublished

    Vikunja has HTML Injection via Task Titles in Overdue Email Notifications

    CVE-2026-35600 · GHSA-45q4-x4r9-8fqj

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    Task titles are embedded directly into Markdown link syntax in overdue email notifications without escaping Markdown special characters. When rendered by goldmark and sanitized by bluemonday (which allows <a and <img tags), injected Markdown constructs produce phishing links and tracking pixels in legitimate notification emails. Details The overdue task notification at pkg/models/notifications.go:360 constructs a Markdown list entry: The task title is placed inside Markdown link syntax TITLE. A title containing ] and breaks the link structure. The assembled Markdown is converted to HTML by goldmark at pkg/notifications/mailrender.go:214, then sanitized by bluemonday's UGCPolicy. Since UGCPolicy intentionally allows <a href and <img src with http/https URLs, the injected links and images survive sanitization and reach the email recipient. The same pattern affects multiple notification types at notifications.go lines 72, 176, 227, and 318. Proof of Concept Tested on Vikunja…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  11. Medium, CVSS 6.5GoPublished

    Vikunja has Algorithmic Complexity DoS in Repeating Task Handler

    CVE-2026-35599 · GHSA-r4fg-73rc-hhh7

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    The addRepeatIntervalToTime function uses an O(n) loop that advances a date by the task's RepeatAfter duration until it exceeds the current time. By creating a repeating task with a 1-second interval and a due date far in the past, an attacker triggers billions of loop iterations, consuming CPU and holding a database connection for minutes per request. Details The vulnerable function at pkg/models/tasks.go:1456-1464: The RepeatAfter field accepts any positive integer (validated as range(0|9223372036854775807)), and DueDate accepts any valid timestamp including dates far in the past. When a task with repeatafter=1 and duedate=1900-01-01 is marked as done, the loop runs approximately 4 billion iterations (~60+ seconds of CPU time). Each request holds a goroutine and a database connection for the duration. With the default connection pool size of 100, approximately 100 concurrent requests exhaust all available connections. Proof of Concept Tested on Vikunja v2.2.2. Output: The…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  12. Medium, CVSS 4.3GoPublished

    Vikunja Missing Authorization on CalDAV Task Read

    CVE-2026-35598 · GHSA-48ch-p4gq-x46x

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    The CalDAV GetResource and GetResourcesByList methods fetch tasks by UID from the database without verifying that the authenticated user has access to the task's project. Any authenticated CalDAV user who knows (or guesses) a task UID can read the full task data from any project on the instance. Details GetTasksByUIDs at pkg/models/tasks.go:376-393 performs a global database query with no authorization check: The web.Auth parameter is accepted but never used for permission filtering. This function is called by: - GetResource at pkg/routes/caldav/listStorageProvider.go:266 (CalDAV GET) - GetResourcesByList at pkg/routes/caldav/listStorageProvider.go:199 (CalDAV REPORT multiget) All other CalDAV operations enforce authorization: CreateResource checks CanCreate(), UpdateResource checks CanUpdate(), DeleteResource checks CanDelete(). Only the read operations skip authorization. The project ID in the CalDAV URL is ignored. A request to…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  13. Medium, CVSS 5.9GoPublished

    Vikunja Vulnerable to TOTP Brute-Force Due to Non-Functional Account Lockout

    CVE-2026-35597 · GHSA-fgfv-pv97-6cmj

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    The TOTP failed-attempt lockout mechanism is non-functional due to a database transaction handling bug. The account lock is written to the same database session that the login handler always rolls back on TOTP failure, so the lockout is triggered but never persisted. This allows unlimited brute-force attempts against TOTP codes. Details When a TOTP validation fails, the login handler at pkg/routes/api/v1/login.go:95-101 calls HandleFailedTOTPAuth and then unconditionally rolls back: HandleFailedTOTPAuth at pkg/user/totp.go:201-247 uses an in-memory counter (key-value store) to track failed attempts. When the counter reaches 10, it calls user.SetStatus(s, StatusAccountLocked) on the same database session s. Because the login handler always rolls back after a TOTP failure, the StatusAccountLocked write is undone. The in-memory counter correctly increments past 10, so the lockout code executes on every subsequent attempt, but the database write is rolled back every time. Proof…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  14. Medium, CVSS 4.3GoPublished

    Vikunja has Broken Access Control on Label Read via SQL Operator Precedence Bug

    CVE-2026-35596 · GHSA-hj5c-mhh2-g7jq

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    The hasAccessToLabel function contains a SQL operator precedence bug that allows any authenticated user to read any label that has at least one task association, regardless of project access. Label titles, descriptions, colors, and creator information are exposed. Details The access control query at pkg/models/labelpermissions.go:85-91 uses xorm's query chain in a way that produces SQL without proper grouping: The xorm chain .Where(A OR B).Or(C).And(D) generates SQL: WHERE A OR B OR C AND D. Because SQL AND has higher precedence than OR, this evaluates as WHERE A OR B OR (C AND D). The labels.id = ? constraint (D) only binds to the project access condition (C), while labeltasks.labelid IS NOT NULL (part of A) remains unconstrained. Any label that has at least one task association passes the IS NOT NULL check, regardless of who is requesting it. Proof of Concept Tested on Vikunja v2.2.2. Output: Label IDs are sequential integers, making enumeration straightforward. Impact Any…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  15. High, CVSS 8.3GoPublished

    Vikunja vulnerable to Privilege Escalation via Project Reparenting

    CVE-2026-35595 · GHSA-2vq4-854f-5c72

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    A user with Write-level access to a project can escalate their permissions to Admin by moving the project under a project they own. After reparenting, the recursive permission CTE resolves ownership of the new parent as Admin on the moved project. The attacker can then delete the project, manage shares, and remove other users' access. Details The CanUpdate check at pkg/models/projectpermissions.go:139-148 only requires CanWrite on the new parent project when changing parentprojectid. However, Vikunja's permission model uses a recursive CTE that walks up the project hierarchy to compute permissions. Moving a project under a different parent changes the permission inheritance chain. When a user has inherited Write access (from a parent project share) and reparents the child project under their own project tree, the CTE resolves their ownership of the new parent as Admin (permission level 2) on the moved project. Proof of Concept Tested on Vikunja v2.2.2. Output: The attacker…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  16. Medium, CVSS 6.5GoPublished

    Vikunja: Link Share JWT tokens remain valid for 72 hours after share deletion or permission downgrade

    CVE-2026-35594 · GHSA-96q5-xm3p-7m84

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    Title Link Share JWT tokens remain valid for 72 hours after share deletion or permission downgrade Description Vikunja's link share authentication constructs authorization objects entirely from JWT claims without any server-side database validation. When a project owner deletes a link share or downgrades its permissions, all previously issued JWTs continue to grant the original permission level for up to 72 hours (the default service.jwtttl). GetLinkShareFromClaims at pkg/models/linksharing.go lines 88-119 performs zero database queries — it builds the LinkSharing struct purely from JWT claim values (id, hash, projectid, permission, sharedByID). This struct is passed directly to permission checks: | Function | File | Lines | DB queries | |----------|------|-------|------------| | GetLinkShareFromClaims | linksharing.go | 88-119 | 0 | | Project.CanRead (link share) | projectpermissions.go | 105-108 | 0 | | Project.CanWrite (link share) | projectpermissions.go | 50-53 | 0 | |…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  17. High, CVSS 7.4GoPublished

    Vikunja has TOTP Two-Factor Authentication Bypass via OIDC Login Path

    CVE-2026-34727 · GHSA-8jvc-mcx6-r4cg

    Affected
    • Go code.vikunja.io/api <= 2.2.2
    Fixed in
    2.3.0· Vendor fix available
    Issue
    The OIDC callback handler issues a full JWT token without checking whether the matched user has TOTP two-factor authentication enabled. When a local user with TOTP enrolled is matched via the OIDC email fallback mechanism, the second factor is completely skipped. Details The OIDC callback at pkg/modules/auth/openid/openid.go:185 issues a JWT directly after user lookup: There are zero references to TOTP in the entire pkg/modules/auth/openid/ directory. By contrast, the local login handler at pkg/routes/api/v1/login.go:79-102 correctly implements TOTP verification: When OIDC EmailFallback maps to a local user who has TOTP enabled, the TOTP enrollment is ignored and a full JWT is issued without any second-factor challenge. Proof of Concept Tested on Vikunja v2.2.2 with Dex as the OIDC provider. Setup: - Vikunja configured with emailfallback: true for Dex - Local user alice (id=1) has TOTP enabled Output: Local login correctly requires TOTP (412), but the OIDC path issued a JWT…

    Recommended action: Upgrade to 2.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  18. Critical, CVSS 9.1GoPublished

    Vikunja: Unauthenticated Instance-Wide Data Breach via Link Share Hash Disclosure Chained with Cross-Project Attachment IDOR

    GHSA-2pv8-4c52-mf8j

    Affected
    • Go code.vikunja.io/api <= 2.2.0
    Fixed in
    2.2.1· Vendor fix available
    Issue
    Two independently-exploitable authorization flaws in Vikunja can be chained to allow an unauthenticated attacker to download and delete every file attachment across all projects in a Vikunja instance. The ReadAll endpoint for link shares exposes share hashes (including admin-level shares) to any user with read access, enabling permission escalation. The task attachment ReadOne/GetTaskAttachment endpoint performs permission checks against a user-supplied task ID but fetches the attachment by its own sequential ID without verifying the attachment belongs to that task, enabling cross-project file access. Details Vulnerability 1: Link Share Hash Disclosure (Permission Escalation Entry Point) Tracked in https://github.com/go-vikunja/vikunja/security/advisories/GHSA-8hp8-9fhr-pfm9 The LinkSharing.ReadAll() method in pkg/models/linksharing.go:228-287 returns all link shares for a project, including the Hash field: The ReadAll clears passwords but not hashes: A link share user with…

    Recommended action: Upgrade to 2.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  19. Medium, CVSS 6.9GoPublished

    Vikunja has a Link Share Delete IDOR — Missing Project Ownership Check Allows Cross-Project Link Share Deletion

    CVE-2026-33700 · GHSA-f95f-77jx-fcjc

    Affected
    • Go code.vikunja.io/api < 2.2.1
    Fixed in
    2.2.1· Vendor fix available
    Issue
    The DELETE /api/v1/projects/:project/shares/:share endpoint does not verify that the link share belongs to the project specified in the URL. An attacker with admin access to any project can delete link shares from other projects by providing their own project ID combined with the target share ID. Details The permission check in canDoLinkShare (pkg/models/linksharingpermissions.go:53-70) validates admin access on the project from the :project URL parameter. However, the Delete method at pkg/models/linksharing.go:305 queries only WHERE id = ? using the share ID, without verifying it belongs to the URL-specified project: This is the same vulnerability class as GHSA-jfmm-mjcp-8wq2 (task attachment IDOR) and the fixed GHSA-mr3j-p26x-72x4 (task comment IDOR). Additionally, ReadOne at line 203 has the same pattern (WHERE id = ? only), though it is not currently exploitable because CanRead fails first due to an unrelated issue with the hash parameter binding. Impact An authenticated…

    Recommended action: Upgrade to 2.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  20. High, CVSS 7.5GoPublished

    Vikjuna: Link Share Hash Disclosure via ReadAll Endpoint Enables Permission Escalation

    CVE-2026-33680 · GHSA-8hp8-9fhr-pfm9

    Affected
    • Go code.vikunja.io/api < 2.2.2
    Fixed in
    2.2.2· Vendor fix available
    Issue
    The LinkSharing.ReadAll() method allows link share authenticated users to list all link shares for a project, including their secret hashes. While LinkSharing.CanRead() correctly blocks link share users from reading individual shares via ReadOne, the ReadAllWeb handler bypasses this check by never calling CanRead(). An attacker with a read-only link share can retrieve hashes for write or admin link shares on the same project and authenticate with them, escalating to full admin access. Details The vulnerability arises from an inconsistency between the ReadOneWeb and ReadAllWeb generic handlers and the LinkSharing permission model. LinkSharing.CanRead() correctly blocks link share users (pkg/models/linksharingpermissions.go:25-29): ReadOneWeb calls CanRead() before returning data (pkg/web/handler/readone.go:64): ReadAllWeb does NOT call CanRead() (pkg/web/handler/readall.go:106): LinkSharing.ReadAll() only checks project-level read access (pkg/models/linksharing.go:228-236):…

    Recommended action: Upgrade to 2.2.2 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  21. Medium, CVSS 6.4GoPublished

    Vikjuna Bypasses Webhook SSRF Protections During OpenID Connect Avatar Download

    CVE-2026-33679 · GHSA-g9xj-752q-xh63

    Affected
    • Go code.vikunja.io/api <= 2.2.0
    Fixed in
    2.2.1· Vendor fix available
    Issue
    The DownloadImage function in pkg/utils/avatar.go uses a bare http.Client{} with no SSRF protection when downloading user avatar images from the OpenID Connect picture claim URL. An attacker who controls their OIDC profile picture URL can force the Vikunja server to make HTTP GET requests to arbitrary internal or cloud metadata endpoints. This bypasses the SSRF protections that are correctly applied to the webhook system. Details When a user authenticates via OpenID Connect, Vikunja extracts the picture claim from the ID token or UserInfo endpoint and passes it to syncUserAvatarFromOpenID, which calls utils.DownloadImage with the attacker-controlled URL: Claim extraction (pkg/modules/auth/openid/openid.go:70-78): Avatar sync trigger (pkg/modules/auth/openid/openid.go:348-352): Vulnerable download (pkg/utils/avatar.go:94-115): In contrast, the webhook system correctly applies SSRF protection (pkg/models/webhooks.go:306-310): The avatar download path has none of this…

    Recommended action: Upgrade to 2.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  22. High, CVSS 8.1GoPublished

    Vikjuna: IDOR in Task Attachment ReadOne Allows Cross-Project File Access and Deletion

    CVE-2026-33678 · GHSA-jfmm-mjcp-8wq2

    Affected
    • Go code.vikunja.io/api <= 2.2.0
    Fixed in
    2.2.1· Vendor fix available
    Issue
    TaskAttachment.ReadOne() queries attachments by ID only (WHERE id = ?), ignoring the task ID from the URL path. The permission check in CanRead() validates access to the task specified in the URL, but ReadOne() loads a different attachment that may belong to a task in another project. This allows any authenticated user to download or delete any attachment in the system by providing their own accessible task ID with a target attachment ID. Attachment IDs are sequential integers, making enumeration trivial. Details The vulnerability is in pkg/models/taskattachment.go in the ReadOne method: The permission check in pkg/models/taskattachmentpermissions.go validates access to the URL task, not the attachment's actual task: The TaskAttachment struct binds URL parameters via struct tags (param:"task" and param:"attachment"): Attack flow for read (GET): The custom handler at pkg/routes/api/v1/taskattachment.go:156 calls CanRead (checks URL task) then ReadOne (loads attachment by ID…

    Recommended action: Upgrade to 2.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  23. Medium, CVSS 6.5GoPublished

    Vikjuna: Webhook BasicAuth Credentials Exposed to Read-Only Project Collaborators via API

    CVE-2026-33677 · GHSA-7c2g-p23p-4jg3

    Affected
    • Go code.vikunja.io/api <= 2.2.0
    Fixed in
    2.2.1· Vendor fix available
    Issue
    The GET /api/v1/projects/:project/webhooks endpoint returns webhook BasicAuth credentials (basicauthuser and basicauthpassword) in plaintext to any user with read access to the project. While the existing code correctly masks the HMAC secret field, the BasicAuth fields added in a later migration were not given the same treatment. This allows read-only collaborators to steal credentials intended for authenticating against external webhook receivers. Details When listing project webhooks, the ReadAll method in pkg/models/webhooks.go (line 203) only requires project read access: The Webhook struct defines both fields with JSON serialization tags, so they are included in API responses: The BasicAuth fields were added in migration 20260123000717 ("Add basic auth to webhooks"), but the credential masking logic at line 238 was not updated to include these new fields. The same issue exists in the user webhook listing at pkg/routes/api/v1/userwebhooks.go:65, where Secret is masked but…

    Recommended action: Upgrade to 2.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  24. Medium, CVSS 6.5GoPublished

    Vikunja has Cross-Project Information Disclosure via Task Relations — Missing Authorization Check on Related Task Read

    CVE-2026-33676 · GHSA-8cmm-j6c4-rr8v

    Affected
    • Go code.vikunja.io/api <= 2.2.0
    Fixed in
    2.2.1· Vendor fix available
    Issue
    When the Vikunja API returns tasks, it populates the relatedtasks field with full task objects for all related tasks without checking whether the requesting user has read permission on those tasks' projects. An authenticated user who can read a task that has cross-project relations will receive full details (title, description, due dates, priority, percent completion, project ID, etc.) of tasks in projects they have no access to. Details The vulnerability is in addRelatedTasksToTasks() at pkg/models/tasks.go:496-548. This function is called by addMoreInfoToTasks() (line 773) during every task read operation — both project task listings (GET /api/v1/projects/{id}/views/{id}/tasks) and single task reads (GET /api/v1/tasks/{id}). The function fetches all related tasks directly from the database without any permission filtering: The a web.Auth parameter is received but only used for determining favorites (line 519), never for access control on the related tasks themselves. In…

    Recommended action: Upgrade to 2.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  25. Medium, CVSS 6.4GoPublished

    Vikunja has SSRF via Todoist/Trello Migration File Attachment URLs that Allows Reading Internal Network Resources

    CVE-2026-33675 · GHSA-g66v-54v9-52pr

    Affected
    • Go code.vikunja.io/api <= 2.2.0
    Fixed in
    2.2.1· Vendor fix available
    Issue
    The migration helper functions DownloadFile and DownloadFileWithHeaders in pkg/modules/migration/helpers.go make arbitrary HTTP GET requests without any SSRF protection. When a user triggers a Todoist or Trello migration, file attachment URLs from the third-party API response are passed directly to these functions, allowing an attacker to force the Vikunja server to fetch internal network resources and return the response as a downloadable task attachment. Details The vulnerability exists because the migration HTTP client uses a plain http.Client{} with no URL validation, no private IP blocklist, no redirect restrictions, and no response size limit. Vulnerable code in pkg/modules/migration/helpers.go:38-59: Call site in Todoist migration (pkg/modules/migration/todoist/todoist.go:433-435): The FileURL is deserialized directly from the Todoist Sync API response (json:"fileurl" tag at line 125) with no validation. Call sites in Trello migration…

    Recommended action: Upgrade to 2.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →