GHSA-W2CH-4XGR-22WW

Vulnerability from github – Published: 2026-10-09 20:54 – Updated: 2026-10-09 20:54
VLAI
Summary
Vikunja: Task relation deletion does not check read access to the other task, allowing cross-project relation removal
Details

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.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.5.0"
      },
      "package": {
        "ecosystem": "Go",
        "name": "code.vikunja.io/api"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.9"
            },
            {
              "fixed": "2.6.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-285",
      "CWE-862"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-09T20:54:52Z",
    "nvd_published_at": null,
    "severity": "LOW"
  },
  "details": "## Summary\n\nDeleting 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\u0027s members.\n\n## Details\n\n`TaskRelation.CanCreate` (`pkg/models/task_relation_permissions.go:32-52`) requires write access on `TaskID` **and** read access on `OtherTaskID`.\n\n`TaskRelation.CanDelete` (`pkg/models/task_relation_permissions.go:25-29`) only checks `Task{ID: rel.TaskID}.CanUpdate(s, a)`; `OtherTaskID` is never authorized.\n\n`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.\n\nAffects `DELETE /api/v1/tasks/{id}/relations/{kind}/{otherTaskId}` and the equivalent v2 endpoint.\n\n## Impact\n\nLow, 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\u0027s owner sees the relation vanish without indication of who removed it.\n\nPreconditions: the attacker has write access to a project containing a task that is already related to a task in a project they cannot access.\n\n## Proof of Concept\n\n1. As `owner`, create project `P_near` with task `near` and project `P_far` with task `far`.\n2. Share `P_near` with `attacker` at write permission (`permission: 1`). Do not share `P_far`.\n3. As `owner`: `PUT /api/v1/tasks/{near}/relations` with `{\"other_task_id\": far, \"relation_kind\": \"related\"}` -\u003e 200.\n4. As `attacker`: `GET /api/v1/tasks/{far}` -\u003e 403 (confirms no access).\n5. As `attacker`: `PUT /api/v1/tasks/{near}/relations` with the same body -\u003e 403 (create path is enforced).\n6. As `attacker`: `DELETE /api/v1/tasks/{near}/relations/related/{far}` -\u003e 200 `\"Successfully deleted.\"`\n7. As `owner`: `GET /api/v1/tasks/{far}` -\u003e `related_tasks` is now empty.\n\nReproduced against `vikunja/vikunja:2.5.0`.\n\n## Recommended Fix\n\nMake `CanDelete` mirror `CanCreate`: after checking `CanUpdate` on the base task, also require `CanRead` on `OtherTaskID`.",
  "id": "GHSA-w2ch-4xgr-22ww",
  "modified": "2026-10-09T20:54:52Z",
  "published": "2026-10-09T20:54:52Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/go-vikunja/vikunja/security/advisories/GHSA-w2ch-4xgr-22ww"
    },
    {
      "type": "WEB",
      "url": "https://github.com/go-vikunja/vikunja/pull/3688"
    },
    {
      "type": "WEB",
      "url": "https://github.com/go-vikunja/vikunja/commit/077dc4de79ce6f1ab59215a2c7bf9b30423685f2"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/go-vikunja/vikunja"
    },
    {
      "type": "WEB",
      "url": "https://github.com/go-vikunja/vikunja/releases/tag/v2.6.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "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",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Vikunja: Task relation deletion does not check read access to the other task, allowing cross-project relation removal"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.