GHSA-w2ch-4xgr-22ww
Vikunja: Task relation deletion does not check read access to the other task, allowing cross-project relation removal
Summary
Deleting a task relation only requires write access on the base task. Unlike relation creation, it does not verify that the caller can read the other task. A user with write access to one project can therefore delete relations whose other end lives in a project they have no access to. Since the delete removes both the forward and inverse rows, the relation also disappears for the other project's members.
Details
TaskRelation.CanCreate (pkg/models/task_relation_permissions.go:32-52) requires write access on TaskID and read access on OtherTaskID.
TaskRelation.CanDelete (pkg/models/task_relation_permissions.go:25-29) only checks Task{ID: rel.TaskID}.CanUpdate(s, a); OtherTaskID is never authorized.
TaskRelation.Delete (pkg/models/task_relation.go:314-354) then deletes both the (task_id, other_task_id, kind) row and its inverse, so the relation is removed from the far task as well.
Affects DELETE /api/v1/tasks/{id}/relations/{kind}/{otherTaskId} and the equivalent v2 endpoint.
Impact
Low, integrity only. An authenticated user holding write permission on a shared project can remove task relations that link into projects they cannot read. No data is disclosed and no privilege is gained; the attacker cannot recreate the relation. The far project's owner sees the relation vanish without indication of who removed it.
Preconditions: the attacker has write access to a project containing a task that is already related to a task in a project they cannot access.
Proof of Concept
- As
owner, create projectP_nearwith tasknearand projectP_farwith taskfar. - Share
P_nearwithattackerat write permission (permission: 1). Do not shareP_far. - As
owner:PUT /api/v1/tasks/{near}/relationswith{"other_task_id": far, "relation_kind": "related"}-> 200. - As
attacker:GET /api/v1/tasks/{far}-> 403 (confirms no access). - As
attacker:PUT /api/v1/tasks/{near}/relationswith the same body -> 403 (create path is enforced). - As
attacker:DELETE /api/v1/tasks/{near}/relations/related/{far}-> 200"Successfully deleted." - As
owner:GET /api/v1/tasks/{far}->related_tasksis now empty.
Reproduced against vikunja/vikunja:2.5.0.
Recommended Fix
Make CanDelete mirror CanCreate: after checking CanUpdate on the base task, also require CanRead on OtherTaskID.
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
- None
- Integrity
- Low
- Availability
- None
What each source reports
GitHub Advisories Score used 2.3
Vikunja: Task relation deletion does not check read access to the other task, allowing cross-project relation removal
Summary
Deleting a task relation only requires write access on the base task. Unlike relation creation, it does not verify that the caller can read the other task. A user with write access to one project can therefore delete relations whose other end lives in a project they have no access to. Since the delete removes both the forward and inverse rows, the relation also disappears for the other project's members.
Details
TaskRelation.CanCreate (pkg/models/task_relation_permissions.go:32-52) requires write access on TaskID and read access on OtherTaskID.
TaskRelation.CanDelete (pkg/models/task_relation_permissions.go:25-29) only checks Task{ID: rel.TaskID}.CanUpdate(s, a); OtherTaskID is never authorized.
TaskRelation.Delete (pkg/models/task_relation.go:314-354) then deletes both the (task_id, other_task_id, kind) row and its inverse, so the relation is removed from the far task as well.
Affects DELETE /api/v1/tasks/{id}/relations/{kind}/{otherTaskId} and the equivalent v2 endpoint.
Impact
Low, integrity only. An authenticated user holding write permission on a shared project can remove task relations that link into projects they cannot read. No data is disclosed and no privilege is gained; the attacker cannot recreate the relation. The far project's owner sees the relation vanish without indication of who removed it.
Preconditions: the attacker has write access to a project containing a task that is already related to a task in a project they cannot access.
Proof of Concept
- As
owner, create projectP_nearwith tasknearand projectP_farwith taskfar. - Share
P_nearwithattackerat write permission (permission: 1). Do not shareP_far. - As
owner:PUT /api/v1/tasks/{near}/relationswith{"other_task_id": far, "relation_kind": "related"}-> 200. - As
attacker:GET /api/v1/tasks/{far}-> 403 (confirms no access). - As
attacker:PUT /api/v1/tasks/{near}/relationswith the same body -> 403 (create path is enforced). - As
attacker:DELETE /api/v1/tasks/{near}/relations/related/{far}-> 200"Successfully deleted." - As
owner:GET /api/v1/tasks/{far}->related_tasksis now empty.
Reproduced against vikunja/vikunja:2.5.0.
Recommended Fix
Make CanDelete mirror CanCreate: after checking CanUpdate on the base task, also require CanRead on OtherTaskID.
- Record
GHSA-w2ch-4xgr-22ww- CVSS 4.0
- 2.3 Low
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-285, CWE-862
- Updated
- 2026-11-02
OSV 2.3
Vikunja: Task relation deletion does not check read access to the other task, allowing cross-project relation removal
Summary
Deleting a task relation only requires write access on the base task. Unlike relation creation, it does not verify that the caller can read the other task. A user with write access to one project can therefore delete relations whose other end lives in a project they have no access to. Since the delete removes both the forward and inverse rows, the relation also disappears for the other project's members.
Details
TaskRelation.CanCreate (pkg/models/task_relation_permissions.go:32-52) requires write access on TaskID and read access on OtherTaskID.
TaskRelation.CanDelete (pkg/models/task_relation_permissions.go:25-29) only checks Task{ID: rel.TaskID}.CanUpdate(s, a); OtherTaskID is never authorized.
TaskRelation.Delete (pkg/models/task_relation.go:314-354) then deletes both the (task_id, other_task_id, kind) row and its inverse, so the relation is removed from the far task as well.
Affects DELETE /api/v1/tasks/{id}/relations/{kind}/{otherTaskId} and the equivalent v2 endpoint.
Impact
Low, integrity only. An authenticated user holding write permission on a shared project can remove task relations that link into projects they cannot read. No data is disclosed and no privilege is gained; the attacker cannot recreate the relation. The far project's owner sees the relation vanish without indication of who removed it.
Preconditions: the attacker has write access to a project containing a task that is already related to a task in a project they cannot access.
Proof of Concept
- As
owner, create projectP_nearwith tasknearand projectP_farwith taskfar. - Share
P_nearwithattackerat write permission (permission: 1). Do not shareP_far. - As
owner:PUT /api/v1/tasks/{near}/relationswith{"other_task_id": far, "relation_kind": "related"}-> 200. - As
attacker:GET /api/v1/tasks/{far}-> 403 (confirms no access). - As
attacker:PUT /api/v1/tasks/{near}/relationswith the same body -> 403 (create path is enforced). - As
attacker:DELETE /api/v1/tasks/{near}/relations/related/{far}-> 200"Successfully deleted." - As
owner:GET /api/v1/tasks/{far}->related_tasksis now empty.
Reproduced against vikunja/vikunja:2.5.0.
Recommended Fix
Make CanDelete mirror CanCreate: after checking CanUpdate on the base task, also require CanRead on OtherTaskID.
- Record
GHSA-w2ch-4xgr-22ww- CVSS 4.0
- 2.3 Low
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-285, CWE-862
- Updated
- 2026-11-02
OSVGO-2026-6754No score
Vikunja: Task relation deletion does not check read access to the other task, allowing cross-project relation removal in code.vikunja.io/api
Vikunja: Task relation deletion does not check read access to the other task, allowing cross-project relation removal 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 from v0.9.0 before v2.6.0.
- Record
GO-2026-6754- Updated
- 2026-11-02
Affected packages
| Package | Affected | Fixed |
|---|---|---|
code.vikunja.io/apiGo | 0.9 to 2.5.0 | 2.6.0 |
code.vikunja.io/apiGo | 0.9 up to 2.6.0 | 2.6.0 |
code.vikunja.io/apiGo | All versions | None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | GitHub Advisories, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
GHSA-w2ch-4xgr-22ww is a low vulnerability (CVSS 2.3) in code.vikunja.io/api, published October 9, 2026. No source lists public exploit code. Fixed in code.vikunja.io/api 2.6.0.
References
github.com/go-vikunja/vikunja/security/advisories/GHSA-w2ch-4xgr-22ww
github.com/go-vikunja/vikunja/pull/3688
github.com/go-vikunja/vikunja/commit/077dc4de79ce6f1ab59215a2c7bf9b30423685f2
github.com/go-vikunja/vikunja/releases/tag/v2.6.0
github.com/advisories/GHSA-w2ch-4xgr-22ww
github.com/go-vikunja/vikunja