Mar 26, 2026·6 min read·22 visits
Chaining an authorization bypass in the link-sharing API and an IDOR in the attachment handler allows an attacker with a read-only link to extract administrative tokens and access arbitrary files across the entire Vikunja instance.
A critical vulnerability chain in the Vikunja task management platform allows unauthenticated or minimally authenticated attackers to perform an instance-wide data breach. By combining a link-share hash disclosure (CVE-2026-33680) with a task attachment IDOR (CVE-2026-33678), attackers can read or delete any file attachment on the system.
Vikunja is an open-source, self-hosted task management platform that provides collaboration features, including project sharing and file attachments. The platform exposes a REST API to facilitate client-server communication. Two distinct vulnerabilities, identified as CVE-2026-33680 and CVE-2026-33678, reside within this API infrastructure.
CVE-2026-33680 is an Improper Authorization (CWE-285) vulnerability in the link-sharing mechanism. It permits an actor with read-only access to extract the authentication hashes of higher-privileged link shares. CVE-2026-33678 is an Insecure Direct Object Reference (CWE-639) within the task attachment functionality. It allows authenticated users to access arbitrary attachments across the entire instance.
When chained together, these vulnerabilities yield an advisory categorized under GHSA-2PV8-4C52-MF8J. An attacker possessing a single, low-privileged read-only link share can systematically elevate their privileges and compromise the confidentiality and integrity of all file attachments hosted on the Vikunja instance.
The foundation of the attack relies on architectural inconsistencies within Vikunja's generic Create, Read, Update, Delete (CRUD) handler implementation. The ReadAllWeb handler is responsible for listing collections of objects. This handler neglected to enforce the model-level CanRead() permission check with sufficient granularity for link shares.
In the pkg/models/link_sharing.go module, the ReadAll() method validated access by verifying project.CanRead(s, a). A session established via a link share intrinsically possesses project-level read access, satisfying this preliminary check. Consequently, the API returned the complete list of link shares for the requested project, inadvertently including the secret hash field used as the bearer token for each share.
The second component of the vulnerability chain resides in the task attachment model. The database lookup function for attachments retrieved records based solely on the unique attachment ID. The query execution failed to bind the attachment lookup to the specific task ID provided in the URL path and verified by the authorization layer. This disconnection between the authorized task identifier and the retrieved attachment identifier created the IDOR vulnerability.
The link-share hash disclosure originates in the ReadAll method. Prior to the patch, the system allowed link-share authenticated users to execute the function without explicit restrictions against listing peer shares. The commit 9efe1fadba817923c7c7f5953c3e9e9c5683bbf3 introduced a hard block for link-share users.
// Vulnerable Implementation
func (l *LinkSharing) ReadAll(s *xorm.Session, a web.Auth) (interface{}, error) {
// Missing check for link share auth types
shares := make([]*LinkSharing, 0)
err := s.Where("project_id = ?", l.ProjectID).Find(&shares)
return shares, err
}
// Patched Implementation (Commit 9efe1fadba817923c7c7f5953c3e9e9c5683bbf3)
func (l *LinkSharing) ReadAll(s *xorm.Session, a web.Auth) (interface{}, error) {
if _, is := a.(*LinkSharing); is {
return nil, ErrGenericForbidden{}
}
// ... execution continues to fetch shares for valid users
}Commit 5cd5dc409bfc807f79dac5e4ef4aec54b6efd6e2 further restricted the endpoint by requiring explicit administrator privileges to list project shares. This enforces a principle of least privilege, ensuring standard users cannot enumerate collaboration links.
The attachment IDOR fix required modifying the ReadOne() method to enforce the contextual relationship between the task and the attachment. The patched implementation actively verifies that the TaskID of the retrieved attachment record matches the TaskID specified in the authorized request path, effectively neutralizing the IDOR vector.
The exploitation process requires the attacker to secure initial access via a valid 'Link Share' URL. This URL is often distributed publicly or semi-publicly for collaboration purposes. Upon obtaining this link, the attacker extracts the bearer token and authenticates against the Vikunja API.
The attacker issues a GET request to /api/v1/projects/{id}/shares. The API response contains an array of all active shares for the project. The attacker parses this JSON response to locate a share object possessing 'Admin' or 'Write' privileges and extracts the associated secret hash string.
Using the extracted high-privileged hash, the attacker configures their API client to use the new bearer token. They now have complete administrative control over the targeted project. The attacker selects a valid task ID within this project to satisfy the preliminary TaskAttachment permission check.
The attacker initiates a loop, issuing GET and DELETE requests to /api/v1/tasks/{validTaskId}/attachments/{targetAttachmentId}. They increment the targetAttachmentId integer sequentially. The application validates that the attacker has access to {validTaskId}, but serves the file corresponding to {targetAttachmentId}, allowing the extraction or destruction of all files across the platform.
The chained execution of CVE-2026-33680 and CVE-2026-33678 results in an instance-wide data breach. The primary impact is a severe loss of confidentiality. An attacker can systematically download every file attachment uploaded to the Vikunja server, bypassing all project and user isolation boundaries.
The secondary impact involves a total loss of integrity for the stored attachments. The authorization bypass extends to file deletion mechanisms. An attacker can issue HTTP DELETE requests using the same sequential IDOR technique to permanently remove attachments from the server's storage backend and database.
The vulnerability requires minimal prerequisites. The attacker only needs a single valid link share, which requires no registered user account on the target system. The attack complexity is low, and the process can be fully automated using standard HTTP client libraries, maximizing the potential for rapid data exfiltration before detection.
The vendor addressed both vulnerabilities in a sequence of rapid patches. Version 2.2.1 implemented the initial mitigation by directly blocking link-share authenticated callers from accessing the ReadAll() endpoint for project shares. This version also corrected the database query logic in TaskAttachment.ReadOne() to enforce task-ID binding.
Version 2.2.2 introduced structural security hardening. The backend was updated to strictly require project-level administration rights to list link shares. Additionally, commit 74d1bddb3ab32fc8983d778bb65e89b1d50227d6 implemented client-side visibility controls, completely hiding the sharing section in the user interface for non-administrative accounts.
Administrators must update their Vikunja deployments to version 2.2.2 or later immediately. Organizations unable to patch immediately should disable the link-sharing feature entirely or restrict network access to the API endpoints using a Web Application Firewall. Existing link shares should be audited and revoked if suspicious access patterns are detected in the application logs.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Vikunja Vikunja | < 2.2.1 | 2.2.1 |
Vikunja Vikunja | < 2.2.2 | 2.2.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-285, CWE-639 |
| Attack Vector | Network |
| CVSS Score | 8.1 |
| Impact | High Confidentiality, High Integrity |
| Exploit Status | weaponized |
| KEV Status | Not Listed |
Improper Authorization and Insecure Direct Object Reference
An observable timing discrepancy vulnerability (CWE-208) in Filament's administrative login page allows unauthenticated remote attackers to determine the existence of registered email addresses. This timing side-channel arises from short-circuiting logic that skips expensive password hashing checks when a queried email address is not found in the database. Attackers can execute statistical timing attacks to map active administrator accounts, facilitating subsequent targeted brute-force or credential-stuffing campaigns.
Filament's ImageColumn (used in tables) and ImageEntry (used in infolists) components render database values inside HTML attributes without validation or sanitization. This allows an attacker to inject arbitrary HTML attributes, leading to Stored Cross-Site Scripting (XSS).
The Netty incubator codec for Oblivious HTTP (OHTTP) fails to verify that a cryptographically signed final chunk is received before the outer HTTP body terminates. This missing validation allows an on-path adversary to truncate chunked-OHTTP messages cleanly at a non-final chunk boundary, leading to undetected data truncation and compromising message integrity. The vulnerability affects multiple versions of the maven package io.netty.incubator:netty-incubator-codec-ohttp prior to 0.0.22.Final.
Prior to version 4.1.4, phpMyFAQ used the cryptographically broken SHA-1 algorithm to hash custom attachment encryption keys stored in the database. Attackers with database access can recover these plaintext keys through offline brute-force attacks and subsequently decrypt sensitive file attachments.
A privilege escalation vulnerability in Snipe-IT versions prior to 8.6.0 allows authenticated users with profile-editing capabilities to elevate their own permissions by performing a PATCH request on their own user endpoint.
CVE-2026-48500 is an authorization bypass vulnerability within Filament, a full-stack Laravel administration panel suite. The flaw arises from the unauthenticated exposure of Livewire's file upload RPC endpoints on guest-facing pages, allowing remote actors to upload arbitrary files to temporary storage, potentially leading to storage exhaustion and service disruption.