Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐹 Go
Not in CISA KEV

Vikunja: Task relation deletion does not check read access to the other task, allowing cross-project relation removalGHSA-w2ch-4xgr-22ww

Fix: go-vikunja/vikunja#3688

GHSA-w2ch-4xgr-22ww is a security vulnerability in code.vikunja.io/api. A fix is available for code.vikunja.io/api — see the affected versions and patch details below.

Also known asGO-2026-6754
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 19, 2026 · OSV.dev, FIRST.org (EPSS)

Real-World Exposure

1 pkg affected
🐹code.vikunja.io/api

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.

Description

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

  1. As owner, create project P_near with task near and project P_far with task far.
  2. Share P_near with attacker at write permission (permission: 1). Do not share P_far.
  3. As owner: PUT /api/v1/tasks/{near}/relations with {"other_task_id": far, "relation_kind": "related"} -> 200.
  4. As attacker: GET /api/v1/tasks/{far} -> 403 (confirms no access).
  5. As attacker: PUT /api/v1/tasks/{near}/relations with the same body -> 403 (create path is enforced).
  6. As attacker: DELETE /api/v1/tasks/{near}/relations/related/{far} -> 200 "Successfully deleted."
  7. As owner: GET /api/v1/tasks/{far} -> related_tasks is 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.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐹Gocode.vikunja.io/api≥ 0.9&&< 2.6.02.6.0go get code.vikunja.io/api@v2.6.0

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for code.vikunja.io/api, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update code.vikunja.io/api to 2.6.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-w2ch-4xgr-22ww is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

Frequently Asked Questions

## 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.CanDe
O3 Security · Impact-Aware SCA

Is GHSA-w2ch-4xgr-22ww in your dependencies?

Find it across Go, including transitive dependencies.

Vikunja: Task relation deletion does not check read…