{"id":"CVE-2026-68581","kind":"vulnerability","aliases":["CVE-2026-68581","GHSA-vvcv-vpph-h844","GO-2026-6753"],"related":[],"title":"Vikunja: Link-share principal ID collision allows cross-account API token issuance and management in code.vikunja.io/api","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.","summary":"Vikunja 0.22.0 through 2.3.0 does not check whether a JWT belongs to a user or a link share, so a link-share ID can match a target user's numeric ID. An authenticated attacker can then list, create and delete that user's API tokens, including tokens with attacker-chosen scopes.","severity":"high","cvss":8.6,"epss":0.00464,"exploited":false,"exploited_at":null,"products":[{"name":"code.vikunja.io/api","fixed":[],"affected":">= 0.22.0","ecosystem":"go"}],"ecosystems":["go"],"tags":["api-tokens","go","package","self-hosted","vikunja"],"not_affected_if":["version-2.4.0-or-later","version-below-0.22.0"],"how_to_check":"Check whether the running Vikunja version is between 0.22.0 and 2.3.0. The sources do not give a command.","fix":"Upgrade code.vikunja.io/api to 2.4.0 or later.","status":"open","published_at":"2026-08-02T13:16:54+00:00","first_seen_at":"2026-10-23T19:13:08+00:00","triaged_at":"2026-10-23T21:44:09+00:00","updated_at":"2026-10-23T21:44:09+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-10-23T21:44:09Z","model":"claude-haiku-5-5","output":{"fix":"Upgrade code.vikunja.io/api to 2.4.0 or later.","reach":"internet","impact":"high","summary":"Vikunja 0.22.0 through 2.3.0 does not check whether a JWT belongs to a user or a link share, so a link-share ID can match a target user's numeric ID. An authenticated attacker can then list, create and delete that user's API tokens, including tokens with attacker-chosen scopes.","category":"package","who_cares":["vikunja","self-hosted","go","api-tokens"],"confidence":0.8,"needs_auth":"yes","worst_case":"Attacker takes over target user's account by minting API tokens with arbitrary scopes","analyst_note":"","how_to_check":"Check whether the running Vikunja version is between 0.22.0 and 2.3.0. The sources do not give a command.","needs_analyst":false,"not_affected_if":["version-below-0.22.0","version-2.4.0-or-later"],"user_interaction":"no","needs_special_setup":"unknown","severity_if_unknown":"high"},"cost_usd":0.000864,"input_tokens":3063,"output_tokens":1116,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-2026':22A,30A,33A '-6753':31A '-68581':23A,34A '/api':20A,37A '/api/v1/tokens':156C '0.22.0':48B,102C '2.3.0':50B,104C '2.4.0':229C 'account':11A 'allow':8A 'api':12A,39B,91B,112C,209C 'api-token':38B 'attack':81B,97B,160C,180C,218C 'attacker-chosen':96B,217C 'attacker-writ':179C 'authent':80B,159C,170C 'belong':57B 'check':53B 'chosen':98B,219C 'code.vikunja.io':19A,36A 'code.vikunja.io/api':18A,35A 'collis':7A 'creat':85B,174C,202C 'cross':10A 'cross-account':9A 'cve':21A,32A 'delet':87B,204C 'endpoint':157C 'equal':143C 'fail':105C 'fix':226C 'generic':132C 'ghsa':25A 'ghsa-vvcv-vpph-h844':24A 'go':29A,41B 'h844':28A 'host':45B 'id':6A,70B,78B,117C,122C,142C,148C,168C 'includ':93B,211C 'independ':124C 'interfac':134C 'issu':212C 'issuanc':14A 'jwt':56B,139C,199C 'link':3A,63B,68B,120C,137C,175C,186C,197C 'link-shar':2A,67B,119C,136C,185C,196C 'list':84B,201C 'manag':16A,114C 'match':72B 'new':214C 'numer':77B,125C,141C,166C 'obtain':162C 'packag':42B 'permiss':225C 'princip':5A,109C 'project':182C 'reach':189C 'resolv':129C 'result':195C 'scope':99B,220C 'search':172C 'self':44B 'self-host':43B 'sequenc':126C,188C 'share':4A,64B,69B,121C,138C,176C,187C,198C 'target':74B,145C,164C,206C,223C 'token':13A,40B,92B,94B,113C,210C,215C 'treat':150C 'type':110C 'use':193C 'user':60B,75B,89B,116C,146C,153C,167C,171C,207C 'valid':107C 'valu':191C 'version':101C,228C 'via':169C 'vikunja':1A,46B,47B,100C 'vpph':27A 'vvcv':26A 'web.auth.getid':133C 'whether':54B 'whose':140C 'writabl':181C","nicknames":[],"mitigations":[],"who_affected":null,"tier":null,"verified":{},"analyst_revisit_at":null,"first_public_at":"2026-08-02T13:16:54+00:00","kev":null,"cvss_vector":"CVSS: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_by":"disclosure@vulncheck.com","poc_count":0,"sources":[{"source":"govuln","external_id":"GO-2026-6753","url":"https://pkg.go.dev/vuln/GO-2026-6753","severity":null,"published_at":"2026-10-19T21:08:26+00:00","modified_at":"2026-10-19T21:08:26+00:00","first_seen_at":"2026-10-23T19:13:08+00:00","fetched_at":"2026-10-23T19:13:08+00:00","note":null},{"source":"epss","external_id":"CVE-2026-68581","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-68581","severity":null,"published_at":null,"modified_at":null,"first_seen_at":"2026-10-23T19:13:43+00:00","fetched_at":"2026-10-23T19:13:43+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-68581","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-68581","severity":null,"published_at":"2026-08-02T13:16:54+00:00","modified_at":"2026-09-08T20:34:34+00:00","first_seen_at":"2026-10-23T19:35:23+00:00","fetched_at":"2026-10-23T19:35:23+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}