Vikunja: Read-only project members can obtain any link share's access hash via the single-share read endpoint (v1 and v2) and escalate to the share's permission level
## Summary A user who has only read permission on a project can call the single link-share read endpoint and receive the share's `hash` field — the secret credential that the anonymous `POST /shares/{share}/auth` endpoint exchanges for a link-share JWT carrying the share's permission (read / read-write / admin). A read-only member can therefore mint a write- or admin-level token for the project and perform writes they are not entitled to, while their own user token is correctly refused. This is the remaining variant of the link-share hash disclosure class: GHSA-8hp8-9fhr-pfm9 fixed the list endpoint (ReadAll now requires project admin) but the single-read endpoint's gate was never aligned. Verified on Vikunja 2.5.0; the weak gate has existed since the endpoint, so earlier versions are likely affected too. ## Details Affected endpoints (both verified with a complete chain): - v1: `GET /api/v1/projects/{project}/shares/{share}` - v2: `GET /api/v2/projects/{project}/shares/{share}` Permission gate: `LinkSharing.CanRead` (`pkg/models/link_sharing_permissions.go`) delegates to `project.CanRead(s, a)` — i.e. any user with read access to the project passes. The response serializes the `hash` field (`pkg/models/link_sharing.go`, field tag `json:"hash"`), which is the share's bearer credential. The share `password` field is correctly cleared before returning, but the hash is not restricted. Inconsistent with the sibling list endpoint `GET /projects/{project}/shares` (`LinkSharing.Read
- Products
- code.vikunja.io/api
- Affected versions
- Not specified
- Fixed versions
- 2.6.0
- CVEs
- CVE-2026-91985
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 31 Oct 2026, 08:44 UTC · Revision 1
Source evidence
Vikunja: Read-only project members can obtain any link share's access hash via the single-share read endpoint (v1 and v2) and escalate to the share's permission level
core-osv · Original sourcePublished 9 Oct 2026, 20:51 UTC
## Summary A user who has only read permission on a project can call the single link-share read endpoint and receive the share's `hash` field — the secret credential that the anonymous `POST /shares/{share}/auth` endpoint exchanges for a link-share JWT carrying the share's permission (read / read-write / admin). A read-only member can therefore mint a write- or admin-level token for the project and perform writes they are not entitled to, while their own user token is correctly refused. This is the remaining variant of the link-share hash disclosure class: GHSA-8hp8-9fhr-pfm9 fixed the list endpoint (ReadAll now requires project admin) but the single-read endpoint's gate was never aligned. Verified on Vikunja 2.5.0; the weak gate has existed since the endpoint, so earlier versions are likely affected too. ## Details Affected endpoints (both verified with a complete chain): - v1: `GET /api/v1/projects/{project}/shares/{share}` - v2: `GET /api/v2/projects/{project}/shares/{share}` Permission gate: `LinkSharing.CanRead` (`pkg/models/link_sharing_permissions.go`) delegates to `project.CanRead(s, a)` — i.e. any user with read access to the project passes. The response serializes the `hash` field (`pkg/models/link_sharing.go`, field tag `json:"hash"`), which is the share's bearer credential. The share `password` field is correctly cleared before returning, but the hash is not restricted. Inconsistent with the sibling list endpoint `GET /projects/{project}/shares` (`LinkSharing.Read
osv:GHSA-qfwc-vx6f-3g6g
code.vikunja.io/api
Fixed versions: 2.6.0
Complete source record
{
"id": "f69f8306c4d697879b6dfc6333e8fd840dc10664d79226b4b23ff0eec74dbd04",
"url": "https://osv.dev/vulnerability/GHSA-qfwc-vx6f-3g6g",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "Vikunja: Read-only project members can obtain any link share's access hash via the single-share read endpoint (v1 and v2) and escalate to the share's permission level",
"summary": "## Summary A user who has only read permission on a project can call the single link-share read endpoint and receive the share's `hash` field — the secret credential that the anonymous `POST /shares/{share}/auth` endpoint exchanges for a link-share JWT carrying the share's permission (read / read-write / admin). A read-only member can therefore mint a write- or admin-level token for the project and perform writes they are not entitled to, while their own user token is correctly refused. This is the remaining variant of the link-share hash disclosure class: GHSA-8hp8-9fhr-pfm9 fixed the list endpoint (ReadAll now requires project admin) but the single-read endpoint's gate was never aligned. Verified on Vikunja 2.5.0; the weak gate has existed since the endpoint, so earlier versions are likely affected too. ## Details Affected endpoints (both verified with a complete chain): - v1: `GET /api/v1/projects/{project}/shares/{share}` - v2: `GET /api/v2/projects/{project}/shares/{share}` Permission gate: `LinkSharing.CanRead` (`pkg/models/link_sharing_permissions.go`) delegates to `project.CanRead(s, a)` — i.e. any user with read access to the project passes. The response serializes the `hash` field (`pkg/models/link_sharing.go`, field tag `json:\"hash\"`), which is the share's bearer credential. The share `password` field is correctly cleared before returning, but the hash is not restricted. Inconsistent with the sibling list endpoint `GET /projects/{project}/shares` (`LinkSharing.Read",
"evidence": "osv:GHSA-qfwc-vx6f-3g6g",
"products": [
{
"name": {
"value": "code.vikunja.io/api",
"evidence": "/affected/0/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "2.6.0",
"evidence": "/affected/0/ranges"
}
],
"affected_versions": []
}
],
"severity": "high",
"structured": {
"id": "GHSA-qfwc-vx6f-3g6g",
"aliases": [
"CVE-2026-91985",
"GHSA-qfwc-vx6f-3g6g",
"GO-2026-6747"
],
"affected": [
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "0"
},
{
"fixed": "2.6.0"
}
]
}
],
"package": {
"name": "code.vikunja.io/api",
"purl": "pkg:golang/code.vikunja.io/api",
"ecosystem": "Go"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-qfwc-vx6f-3g6g/GHSA-qfwc-vx6f-3g6g.json",
"last_known_affected_version_range": "<= 2.5.0"
}
}
],
"modified": "2026-10-19T21:40:54.885980828Z",
"provider": "osv",
"references": [
"https://github.com/go-vikunja/vikunja/security/advisories/GHSA-qfwc-vx6f-3g6g",
"https://nvd.nist.gov/vuln/detail/CVE-2026-91985",
"https://github.com/go-vikunja/vikunja/pull/3688",
"https://github.com/go-vikunja/vikunja/commit/077dc4de79ce6f1ab59215a2c7bf9b30423685f2",
"https://github.com/go-vikunja/vikunja",
"https://github.com/go-vikunja/vikunja/releases/tag/v2.6.0",
"https://www.vulncheck.com/advisories/vikunja-before-2.6.0-privilege-escalation-via-link-share-hash"
],
"provider_metadata": {
"cwe_ids": [
"CWE-200",
"CWE-639",
"CWE-862"
],
"severity": "HIGH",
"github_reviewed": true,
"nvd_published_at": null,
"github_reviewed_at": "2026-10-09T20:51:29Z"
}
},
"related_cves": [
{
"value": "CVE-2026-91985",
"evidence": "/aliases"
}
],
"security_relevant": true,
"severity_evidence": "/database_specific/severity"
},
"source_id": "core-osv",
"document_id": 376755,
"published_at": "2026-10-09T20:51:29+00:00"
}