Every CVE Search/ Get API key

CVE-2026-68581

Vikunja 0.22.0 through 2.3.0 Authentication Bypass via Principal ID Collision

8.6 HighFix available

Vikunja versions 0.22.0 through 2.3.0 fail to validate the principal type in API token management. Because user IDs and link-share IDs are independent numeric sequences and both resolve through a generic web.Auth.GetID() interface, a link-share JWT whose numeric ID equals a target user's ID is treated as that user by the /api/v1/tokens endpoints. An authenticated attacker can obtain a target's numeric user ID via authenticated user search, then create link shares on an attacker-writable project until the link-share sequence reaches that value, and use the resulting link-share JWT to list, create, and delete the target user's API tokens (including issuing a new token with attacker-chosen scopes under the target's permissions). Fixed in version 2.4.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Exploit likelihood

0.46%Up 0.1 points since Aug 3, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.6

Vikunja 0.22.0 through 2.3.0 Authentication Bypass via Principal ID Collision

Vikunja versions 0.22.0 through 2.3.0 fail to validate the principal type in API token management. Because user IDs and link-share IDs are independent numeric sequences and both resolve through a generic web.Auth.GetID() interface, a link-share JWT whose numeric ID equals a target user's ID is treated as that user by the /api/v1/tokens endpoints. An authenticated attacker can obtain a target's numeric user ID via authenticated user search, then create link shares on an attacker-writable project until the link-share sequence reaches that value, and use the resulting link-share JWT to list, create, and delete the target user's API tokens (including issuing a new token with attacker-chosen scopes under the target's permissions). Fixed in version 2.4.0.

Record
CVE-2026-68581
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
EUVDEUVD-2026-51991 8.6

Vikunja versions 0.22.0 through 2.3.0 fail to validate the principal type in API token management. Because user IDs and link-share IDs are independent numeric sequences and both resolve through a generic web.Auth.GetID() interface, a link-share JWT whose numeric ID equals a target user's ID is treated as that user by the /api/v1/tokens endpoints. An authenticated attacker can obtain a target's numeric user ID via authenticated user search, then create link shares on an attacker-writable project until the link-share sequence reaches that value, and use the resulting link-share JWT to list, create, and delete the target user's API tokens (including issuing a new token with attacker-chosen scopes under the target's permissions). Fixed in version 2.4.0.

Record
EUVD-2026-51991
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-9jrx-vmh8-c6xw 8.6

Duplicate Advisory: Vikunja: Link-share principal ID collision allows cross-account API token issuance and management

Duplicate Advisory

This advisory has been withdrawn because it is a duplicate of GHSA-vvcv-vpph-h844. This link is maintained to preserve external references.

Original Description

Vikunja versions 0.22.0 through 2.3.0 fail to validate the principal type in API token management. Because user IDs and link-share IDs are independent numeric sequences and both resolve through a generic web.Auth.GetID() interface, a link-share JWT whose numeric ID equals a target user's ID is treated as that user by the /api/v1/tokens endpoints. An authenticated attacker can obtain a target's numeric user ID via authenticated user search, then create link shares on an attacker-writable project until the link-share sequence reaches that value, and use the resulting link-share JWT to list, create, and delete the target user's API tokens (including issuing a new token with attacker-chosen scopes under the target's permissions). Fixed in version 2.4.0.

Record
GHSA-9jrx-vmh8-c6xw
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
GitHub AdvisoriesGHSA-vvcv-vpph-h844 8.1

Vikunja: Link-share principal ID collision allows cross-account API token issuance and management

Executive Summary

Vikunja accepts both regular-user JSON Web Tokens (JWTs) and link-share JWTs through its generic authenticated API route group. A link-share JWT resolves to a models.LinkSharing principal whose GetID() method returns the numeric link_shares.id. The API-token management model then treats that generic numeric value as a users.id when it creates, lists, and deletes API tokens.

Because users.id and link_shares.id are independent positive sequences, a link share whose ID equals another user's ID is treated as that user by /api/v1/tokens. An ordinary authenticated attacker can obtain a target's numeric user ID through authenticated user search and create link shares on an attacker-writable project until the link-share sequence reaches that value. The colliding link-share principal can then list the target's API-token metadata, issue a new API token owned by the target, and delete target-owned API tokens. The newly issued token operates with attacker-selected valid API scopes under the target user's existing permissions.

I reviewed the vulnerable v2.3.0 source, the introducing commit, the stable tag history, and the inspected main revision directly. I also reviewed the recorded local HTTP and native-router validation results. Dynamic testing used only a local v2.3.0 Docker deployment with PostgreSQL and synthetic data; I did not test any public, hosted, or otherwise external instance. Historical tags were checked from source rather than exercised dynamically.

| Field | Value | | --- | --- | | Product | Vikunja API | | Status | Validated; disclosure-ready | | Confirmed affected stable versions | v0.22.0 through v2.3.0, inclusive | | Nearest confirmed unaffected stable version | v0.21.0 | | Introducing commit | e6b25bd57b537ef9a72b5acdadf446ca5ef77bfa | | Latest inspected affected main revision | 95b7e673fb5ee407498fa4b13e8b4c57847a4a0b | | Fixed version | Unknown; no verified fix commit or release was identified | | Severity | High, CVSS v3.1 score 8.1 | | Vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N | | Weakness | Primary: CWE-863 (Incorrect Authorization); secondary: CWE-639 |

The stable range is source-based. The issue first became reachable when commit e6b25bd57b... added the authenticated API-token CRUD routes while retaining the generic web.Auth.GetID() ownership model. v0.21.0 does not contain the API-token model or these routes. All containing stable tags from v0.22.0 through v2.3.0 retain the vulnerable source-to-sink tuple. Downstream forks and vendor-specific builds were not assessed.

Background

Two authenticated principal types share one numeric interface

Vikunja's authenticated route group is protected by a common token middleware. That middleware can establish a regular user, an API-token owner, or a link share as the request's web.Auth principal. The /api/v1/tokens handlers are registered on this generic group in pkg/routes/routes.go:

a.Use(SetupTokenMiddleware())

// API Tokens
apiTokenProvider := &handler.WebHandler{
	EmptyStruct: func() handler.CObject {
		return &models.APIToken{}
	},
}
a.GET("/tokens", apiTokenProvider.ReadAllWeb)
a.PUT("/tokens", apiTokenProvider.CreateWeb)
a.DELETE("/tokens/:token", apiTokenProvider.DeleteWeb)

The security-sensitive detail is that authentication answers which object is the principal, while web.Auth.GetID() exposes only an untyped integer. A regular user's ID belongs to the users namespace. A link-share ID belongs to the separately allocated link_shares namespace. Equality between those integers does not imply that the principals represent the same actor.

Link-share authentication preserves the share-row ID

pkg/modules/auth/auth.go creates a link-share JWT with the share's numeric ID and later resolves that token to a models.LinkSharing object:

claims["type"] = AuthTypeLinkShare
claims["id"] = share.ID
claims["hash"] = share.Hash
claims["project_id"] =…
Record
GHSA-vvcv-vpph-h844
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
NVD 8.6

Vikunja versions 0.22.0 through 2.3.0 fail to validate the principal type in API token management. Because user IDs and link-share IDs are independent numeric sequences and both resolve through a generic web.Auth.GetID() interface, a link-share JWT whose numeric ID equals a target user's ID is treated as that user by the /api/v1/tokens endpoints. An authenticated attacker can obtain a target's numeric user ID via authenticated user search, then create link shares on an attacker-writable project until the link-share sequence reaches that value, and use the resulting link-share JWT to list, create, and delete the target user's API tokens (including issuing a new token with attacker-chosen scopes under the target's permissions). Fixed in version 2.4.0.

Record
CVE-2026-68581
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
OSV 8.6

Vikunja 0.22.0 through 2.3.0 Authentication Bypass via Principal ID Collision

Vikunja versions 0.22.0 through 2.3.0 fail to validate the principal type in API token management. Because user IDs and link-share IDs are independent numeric sequences and both resolve through a generic web.Auth.GetID() interface, a link-share JWT whose numeric ID equals a target user's ID is treated as that user by the /api/v1/tokens endpoints. An authenticated attacker can obtain a target's numeric user ID via authenticated user search, then create link shares on an attacker-writable project until the link-share sequence reaches that value, and use the resulting link-share JWT to list, create, and delete the target user's API tokens (including issuing a new token with attacker-chosen scopes under the target's permissions). Fixed in version 2.4.0.

Record
CVE-2026-68581
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-863
Updated
2026-11-02
OSVGHSA-9jrx-vmh8-c6xw 8.6

Duplicate Advisory: Vikunja: Link-share principal ID collision allows cross-account API token issuance and management

Duplicate Advisory

This advisory has been withdrawn because it is a duplicate of GHSA-vvcv-vpph-h844. This link is maintained to preserve external references.

Original Description

Vikunja versions 0.22.0 through 2.3.0 fail to validate the principal type in API token management. Because user IDs and link-share IDs are independent numeric sequences and both resolve through a generic web.Auth.GetID() interface, a link-share JWT whose numeric ID equals a target user's ID is treated as that user by the /api/v1/tokens endpoints. An authenticated attacker can obtain a target's numeric user ID via authenticated user search, then create link shares on an attacker-writable project until the link-share sequence reaches that value, and use the resulting link-share JWT to list, create, and delete the target user's API tokens (including issuing a new token with attacker-chosen scopes under the target's permissions). Fixed in version 2.4.0.

Record
GHSA-9jrx-vmh8-c6xw
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
OSVGHSA-vvcv-vpph-h844 8.1

Vikunja: Link-share principal ID collision allows cross-account API token issuance and management

Executive Summary

Vikunja accepts both regular-user JSON Web Tokens (JWTs) and link-share JWTs through its generic authenticated API route group. A link-share JWT resolves to a models.LinkSharing principal whose GetID() method returns the numeric link_shares.id. The API-token management model then treats that generic numeric value as a users.id when it creates, lists, and deletes API tokens.

Because users.id and link_shares.id are independent positive sequences, a link share whose ID equals another user's ID is treated as that user by /api/v1/tokens. An ordinary authenticated attacker can obtain a target's numeric user ID through authenticated user search and create link shares on an attacker-writable project until the link-share sequence reaches that value. The colliding link-share principal can then list the target's API-token metadata, issue a new API token owned by the target, and delete target-owned API tokens. The newly issued token operates with attacker-selected valid API scopes under the target user's existing permissions.

I reviewed the vulnerable v2.3.0 source, the introducing commit, the stable tag history, and the inspected main revision directly. I also reviewed the recorded local HTTP and native-router validation results. Dynamic testing used only a local v2.3.0 Docker deployment with PostgreSQL and synthetic data; I did not test any public, hosted, or otherwise external instance. Historical tags were checked from source rather than exercised dynamically.

| Field | Value | | --- | --- | | Product | Vikunja API | | Status | Validated; disclosure-ready | | Confirmed affected stable versions | v0.22.0 through v2.3.0, inclusive | | Nearest confirmed unaffected stable version | v0.21.0 | | Introducing commit | e6b25bd57b537ef9a72b5acdadf446ca5ef77bfa | | Latest inspected affected main revision | 95b7e673fb5ee407498fa4b13e8b4c57847a4a0b | | Fixed version | Unknown; no verified fix commit or release was identified | | Severity | High, CVSS v3.1 score 8.1 | | Vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N | | Weakness | Primary: CWE-863 (Incorrect Authorization); secondary: CWE-639 |

The stable range is source-based. The issue first became reachable when commit e6b25bd57b... added the authenticated API-token CRUD routes while retaining the generic web.Auth.GetID() ownership model. v0.21.0 does not contain the API-token model or these routes. All containing stable tags from v0.22.0 through v2.3.0 retain the vulnerable source-to-sink tuple. Downstream forks and vendor-specific builds were not assessed.

Background

Two authenticated principal types share one numeric interface

Vikunja's authenticated route group is protected by a common token middleware. That middleware can establish a regular user, an API-token owner, or a link share as the request's web.Auth principal. The /api/v1/tokens handlers are registered on this generic group in pkg/routes/routes.go:

a.Use(SetupTokenMiddleware())

// API Tokens
apiTokenProvider := &handler.WebHandler{
	EmptyStruct: func() handler.CObject {
		return &models.APIToken{}
	},
}
a.GET("/tokens", apiTokenProvider.ReadAllWeb)
a.PUT("/tokens", apiTokenProvider.CreateWeb)
a.DELETE("/tokens/:token", apiTokenProvider.DeleteWeb)

The security-sensitive detail is that authentication answers which object is the principal, while web.Auth.GetID() exposes only an untyped integer. A regular user's ID belongs to the users namespace. A link-share ID belongs to the separately allocated link_shares namespace. Equality between those integers does not imply that the principals represent the same actor.

Link-share authentication preserves the share-row ID

pkg/modules/auth/auth.go creates a link-share JWT with the share's numeric ID and later resolves that token to a models.LinkSharing object:

claims["type"] = AuthTypeLinkShare
claims["id"] = share.ID
claims["hash"] = share.Hash
claims["project_id"] =…
Record
GHSA-vvcv-vpph-h844
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
OSVGO-2026-6753 No score

Vikunja: Link-share principal ID collision allows cross-account API token issuance and management in code.vikunja.io/api

Vikunja: Link-share principal ID collision allows cross-account API token issuance and management in code.vikunja.io/api.

NOTE: The source advisory for this report contains additional versions that could not be automatically mapped to standard Go module versions.

(If this is causing false-positive reports from vulnerability scanners, please suggest an edit to the report.)

The additional affected modules and versions are: code.vikunja.io/api before v2.4.0.

Record
GO-2026-6753
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
code.vikunja.io/api
Go
0.22.0 to 2.3.0
2.4.0
code.vikunja.io/api
Go
0.22.0 up to 2.4.0
2.4.0
code.vikunja.io/api
Go
0.22.0 and later None known

History

History
RecordedChangedSources
affected
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-68581 is a high vulnerability (CVSS 8.6) in Go-vikunja Vikunja, published August 2, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.46%, the 40th percentile. Fixed in code.vikunja.io/api 2.4.0.

References

Show 4 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open