CVE-2026-35594
Description
Vikunja is an open-source self-hosted task management platform. Prior to 2.3.0, Vikunja's link share authentication (GetLinkShareFromClaims in pkg/models/link_sharing.go) 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). This vulnerability is fixed in 2.3.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
code.vikunja.io/apiGo | < 2.3.0 | 2.3.0 |
Affected products
1Patches
1379d8a5c1933test(security): webtest that a deleted link share rejects its still-valid JWT
1 file changed · +28 −1
pkg/webtests/link_sharing_test.go+28 −1 modified@@ -20,6 +20,7 @@ import ( "net/url" "testing" + "code.vikunja.io/api/pkg/db" "code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/web/handler" @@ -31,7 +32,7 @@ func TestLinkSharing(t *testing.T) { linkshareRead := &models.LinkSharing{ ID: 1, - Hash: "test1", + Hash: "test", // must match pkg/db/fixtures/link_shares.yml id=1 ProjectID: 1, Permission: models.PermissionRead, SharingType: models.SharingTypeWithoutPassword, @@ -807,4 +808,30 @@ func TestLinkSharing(t *testing.T) { }) }) }) + + // Regression test for GHSA-96q5-xm3p-7m84 / CVE-2026-35594: a still-valid + // link share JWT must be rejected once its DB row is gone. + // + // bootstrapTestRequest reloads fixtures, so the row must be deleted + // AFTER bootstrapping, otherwise the reload restores it. + t.Run("Deleted share rejects its still-valid JWT", func(t *testing.T) { + projectReadAllHandler := handler.WebHandler{ + EmptyStruct: func() handler.CObject { + return &models.Project{} + }, + } + + c, _ := bootstrapTestRequest(t, "GET", "", nil, nil) + addLinkShareTokenToContext(t, linkshareRead, c) + + sess := db.NewSession() + defer sess.Close() + _, err := sess.Where("id = ?", 1).Delete(&models.LinkSharing{}) + require.NoError(t, err) + require.NoError(t, sess.Commit()) + + err = projectReadAllHandler.ReadAllWeb(c) + require.Error(t, err) + assertHandlerErrorCode(t, err, models.ErrCodeLinkShareTokenInvalid) + }) }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/go-vikunja/vikunja/commit/379d8a5c19334ffe4846003f590e202c31a75479nvdPatchWEB
- github.com/go-vikunja/vikunja/security/advisories/GHSA-96q5-xm3p-7m84nvdExploitVendor AdvisoryWEB
- github.com/advisories/GHSA-96q5-xm3p-7m84ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-35594ghsaADVISORY
- github.com/go-vikunja/vikunja/pull/2581nvdIssue TrackingWEB
- github.com/go-vikunja/vikunja/releases/tag/v2.3.0nvdRelease NotesWEB
News mentions
0No linked articles in our index yet.