CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-FMMF-XQ98-G327

GHSA-fmmf-xq98-g327: Write-Level Project Members Can Delete Admin-Tier Link Shares in Vikunja

Alon Barad
Alon Barad
Software Engineer

Oct 10, 2026·5 min read·8 visits

Executive Summary (TL;DR)

Write-level collaborators in Vikunja can delete admin-tier link shares due to an authorization check executing on an unpopulated model struct, causing stored admin permissions to evaluate as zero.

An authorization bypass vulnerability in Vikunja's link share deletion handlers allows project members with Write privileges to delete Admin-tier link shares. The handler passes an unpopulated struct to the authorization check, causing the permission evaluation to fall back to default Write permissions instead of requiring Admin privileges.

Vulnerability Overview

Vikunja is an open-source, self-hosted task management platform written in Go (code.vikunja.io/api). The application provides link sharing functionality, enabling project owners and administrators to generate access tokens and URLs for external stakeholders with predefined permissions such as Read, Write, or Admin.

An authorization bypass bug exists in the HTTP handler responsible for deleting project link shares. Under intended access control logic, revoking or deleting an Admin-tier link share requires the requesting user to hold Admin privileges on the parent project. However, the deletion logic fails to retrieve the target link share's stored state from the database prior to evaluating access control.

Because authorization rules are evaluated against an uninitialized Go struct, the internal permission field defaults to zero (PermissionRead). Consequently, the access check grants deletion rights to any user with Write access to the project, violating expected authorization boundaries.

Root Cause Analysis

The root cause of GHSA-fmmf-xq98-g327 stems from incorrect object initialization prior to access control policy evaluation, classified under CWE-863 (Incorrect Authorization).

In pkg/routes/api/v2/link_sharing.go, the HTTP routing handler receives a request to delete a share given a project ID and share ID. Instead of querying the database for the existing LinkSharing record, the handler instantiates an incomplete struct populated only with the route parameter identifiers:

&models.LinkSharing{ID: in.ID, ProjectID: in.ProjectID}

This struct is passed to handler.DoDelete, which invokes LinkSharing.CanDelete. CanDelete delegates evaluation to canDoLinkShare in pkg/models/link_sharing_permissions.go.

Inside canDoLinkShare, the system evaluates whether share.Permission == PermissionAdmin. Because share is an unpopulated struct instance, share.Permission contains the Go zero-value for its integer type, which corresponds to PermissionRead (0) rather than PermissionAdmin (2). The system skips the required IsAdmin check and proceeds to CanWrite. Since the caller possesses Write rights on the project, the check succeeds.

Code Analysis

The vulnerability is visible in the structural binding and decision logic across pkg/routes/api/v2/link_sharing.go and pkg/models/link_sharing_permissions.go.

// Vulnerable Flow in pkg/routes/api/v2/link_sharing.go
func (h *LinkSharingHandler) Delete(c labstack.Context) error {
    var in struct {
        ProjectID int64 `param:"project"`登
        ID        int64 `param:"share"`撘
    }
    // ... binding logic ...
    // Unpopulated model created without database read
    s := &models.LinkSharing{ID: in.ID, ProjectID: in.ProjectID}
    return handler.DoDelete(c, s)
}

During evaluation inside pkg/models/link_sharing_permissions.go:

func canDoLinkShare(s *m.Session, a m.Admin, share *LinkSharing) bool {
    // share.Permission is 0 (zero-value) instead of 2 (PermissionAdmin)
    if share.Permission == PermissionAdmin {
        return l.IsAdmin(s, a)
    }
    // Unloaded check falls through to CanWrite
    return l.CanWrite(s, a)
}

Once CanDelete returns true, handler.DoDelete executes LinkSharing.Delete. The SQL query filters strictly by id and project_id, removing the database row without ever validating whether the actual record had PermissionAdmin assigned.

Exploitation Methodology

Exploitation requires network access to the Vikunja instance and an authenticated session for an account with Write collaborator privileges on a target project.

First, an attacker attempts to create an admin-tier link share to confirm authorization checks on creation endpoints are active:

curl -i -X POST "https://vikunja.local/api/v2/projects/10/shares" \
  -H "Authorization: Bearer WRITER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"permission":2}'

The server correctly returns HTTP 403 Forbidden. However, when targeting an existing admin-tier link share created by the project owner (e.g., share ID 42), the attacker issues a DELETE request:

curl -i -X DELETE "https://vikunja.local/api/v2/projects/10/shares/42" \
  -H "Authorization: Bearer WRITER_TOKEN"

Because share.Permission evaluates to 0 during authorization, the check succeeds, returning HTTP 204 No Content (or HTTP 200 OK on /api/v1/). The target admin-tier link share is permanently deleted from the database.

Impact Assessment

The impact of GHSA-fmmf-xq98-g327 is localized to project link share management and external session persistence.

An attacker holding Write access can destroy administrative share links set up by project owners. In configurations where link-share JWT tokens undergo database validation upon every request, deleting the link share immediately revokes external active sessions, resulting in HTTP 401 Unauthorized errors for external consumers.

The vulnerability does not grant vertical privilege escalation; the attacker cannot acquire administrative privileges within the project, read unauthorized project data, or create new administrative link shares.

Remediation & Mitigation Guidance

To remediate this vulnerability, deletion handlers must pre-fetch the targeted LinkSharing record from the database using both share ID and project ID prior to executing authorization routines.

// Recommended Remediation Pattern
func (h *LinkSharingHandler) Delete(c labstack.Context) error {
    // 1. Fetch existing record from DB
    share, err := models.GetLinkShareByIDAndProject(in.ID, in.ProjectID)
    if err != nil {
        return err
    }
    // 2. Pass fully populated model to authorization and deletion handler
    return handler.DoDelete(c, share)
}

If immediate patching is not possible, instances should restrict Write collaborator access on critical projects or monitor access logs for DELETE operations targeting /api/v1/projects/*/shares/* and /api/v2/projects/*/shares/*.

Technical Appendix

CVSS Score
5.3/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N

Affected Systems

code.vikunja.io/api (Go package)Vikunja API deployments running versions >= 0.13.0 and <= 2.6.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
Vikunja API
Vikunja
>= 0.13.0, <= 2.6.0Unreleased (post-2.6.0 / main branch)
AttributeDetail
CWE IDCWE-863 (Incorrect Authorization)
Attack VectorNetwork
CVSS v4.0 Score5.3 (Medium)
EPSS ScoreN/A (No CVE Assigned)
ImpactUnauthorized deletion of admin-tier project link shares
Exploit StatusProof of Concept available
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
T1070Indicator Removal
Defense Evasion
CWE-863
Incorrect Authorization

The software performs an authorization check when an actor attempts to access a resource, but it does not correctly perform the check, allowing access without required privileges.

Known Exploits & Detection

GitHub Security AdvisoryReproduction steps demonstrating HTTP DELETE requests using Write token against Admin share IDs

Vulnerability Timeline

GitHub Security Advisory GHSA-fmmf-xq98-g327 published
2026-10-09

References & Sources

  • [1]GitHub Security Advisory GHSA-fmmf-xq98-g327
  • [2]Vikunja Source Code Repository
Related Vulnerabilities
CVE-2026-33700CVE-2026-35594

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•35 minutes ago•GHSA-4HV6-XC92-J86G
6.5

GHSA-4HV6-XC92-J86G: Insufficient Session Expiration in Vikunja WebSocket Authentication Pipeline

Vikunja versions 2.3.0 through 2.6.0 contain an insufficient session expiration vulnerability (CWE-613) within the WebSocket authentication handler. Although Vikunja enforces server-side session tracking and revocation for REST API routes, the WebSocket handshake handler validates cryptographic JWT signatures without querying the database session state. Consequently, revoked JWT tokens can establish new real-time WebSocket connections, and existing connections persist after session revocation.

Alon Barad
Alon Barad
1 views•5 min read
•about 2 hours ago•GHSA-FPRF-R6RV-XG99
6.5

GHSA-FPRF-R6RV-XG99: Cross-Tenant Task Position Recalculation in Vikunja

A cross-tenant boundary breach vulnerability in Vikunja allows an authenticated user to trigger global task position recalculations across all tenant instances by creating a saved filter with an empty filter string payload.

Amit Schendel
Amit Schendel
5 views•4 min read
•about 3 hours ago•GHSA-HJX8-QV73-F7CM
6.5

GHSA-HJX8-QV73-F7CM: Incomplete Access Revocation Leading to Webhook Data Exfiltration in Vikunja

An access revocation flaw in Vikunja allows removed collaborators to retain outbound webhooks and link shares created prior to revocation, enabling persistent exfiltration of sensitive task data.

Alon Barad
Alon Barad
5 views•5 min read
•about 4 hours ago•GHSA-PJR3-86V4-5P7W
5.4

GHSA-PJR3-86V4-5P7W: Broken Access Control via MAX Aggregation in Vikunja Subtree Permissions

Vikunja v2.6.0 contains a permission inheritance regression in pkg/models/project_access.go where explicit down-restrictions on sub-projects are overridden by higher parent project permissions due to MAX aggregation across project tree nodes.

Alon Barad
Alon Barad
5 views•6 min read
•about 6 hours ago•GHSA-M687-P538-R5HP
7.2

GHSA-m687-p538-r5hp: Permissive Localhost CORS Policy Leads to Account Takeover in Vikunja

Vikunja versions 2.2.0 through 2.6.0 contain a Cross-Origin Resource Sharing (CORS) misconfiguration flaw in `code.vikunja.io/api`. Default configurations permit wildcard origins for localhost (`http://127.0.0.1:*` and `http://localhost:*`) with credentialed requests (`Access-Control-Allow-Credentials: true`). Because configuring a public service URL appends to this default list rather than overriding it, production environments inadvertently trust all local origins. A local page or application on a user's machine can execute a credentialed cross-origin request to the token refresh endpoint, extract the returned JWT access token, and achieve complete account takeover.

Alon Barad
Alon Barad
8 views•5 min read
•about 12 hours ago•GHSA-JQ7H-WRVP-3RGX
7.5

GHSA-JQ7H-WRVP-3RGX: Insufficient Session Invalidation in pyLoad Core REST API

An insufficient session invalidation vulnerability exists in pyLoad (pyload-ng) versions 0.5.0b3.dev98 through 0.5.0b3.dev101. When administrative actions like privilege revocation or password changes are executed via the public REST API, active user sessions on disk are not updated or invalidated. Consequently, affected sessions remain fully authenticated with stale permissions for up to 31 days.

Amit Schendel
Amit Schendel
8 views•4 min read