Mar 26, 2026·8 min read·3 visits
Improper authorization in Vikunja's link-sharing API exposes admin hashes to read-only users, leading to full project takeover.
Vikunja versions prior to 2.2.2 suffer from an improper authorization vulnerability in the link-sharing mechanism. The ReadAll API endpoint fails to validate permissions correctly, allowing an attacker with a read-only link share to extract authentication hashes for administrative shares. This flaw enables unauthenticated or low-privilege actors to escalate their access to full administrative control over a target project.
Vikunja is an open-source, self-hosted task management platform that allows users to organize projects, track tasks, and collaborate. A core collaboration feature is the ability to generate link shares, which grant external users varying levels of access to specific projects without requiring a full user account. These link shares range from read-only access to full administrative control.
CVE-2026-33680 identifies an improper authorization vulnerability (CWE-285) within the API endpoints responsible for managing these link shares. The system fails to correctly validate permissions when a user requests a list of all active shares for a given project. Because the authorization logic is inconsistently applied across different handler functions, the system processes requests that should normally be rejected.
The core of the issue lies in the disclosure of sensitive authentication material. In Vikunja, the hash associated with a link share acts as a bearer token; possession of the hash grants the associated permissions. By exploiting this vulnerability, an attacker possessing only a read-only token can retrieve the hashes for all other shares, enabling immediate privilege escalation to project administrator.
The root cause of this vulnerability involves a structural discrepancy between how Vikunja handles single-resource retrieval versus multiple-resource listing within its API abstraction layer. The ReadOneWeb handler, which processes requests for a specific link share, explicitly invokes the model's CanRead() method. This method acts as a dedicated authorization gate, correctly blocking users authenticated via link shares from viewing detailed share metadata.
Conversely, the ReadAllWeb generic handler, responsible for processing requests to list resources, omits this explicit CanRead() invocation. Instead of enforcing authorization at the handler level, ReadAllWeb delegates the responsibility entirely to the underlying LinkSharing model's ReadAll() implementation. This architectural decision creates a critical gap where generic listing requests bypass the standard permission boundary.
Within the LinkSharing model, the ReadAll() method implements an insufficient authorization check. The original logic merely verified if the current session possessed project-level read access via the Project.CanRead() function. Because link-share users inherently require read access to the project to view tasks, they easily pass this verification step.
Consequently, the API constructs a JSON response containing an array of all LinkSharing objects associated with the project. Crucially, the data serialization includes the Hash field for each share. The exposure of this field transforms a logical access control flaw into a direct credential leak.
The remediation strategy deployed in version 2.2.2 addresses the vulnerability through a multi-layered approach, directly modifying the authorization requirements within the model. The primary backend fix, implemented in commit 9efe1fadba817923c7c7f5953c3e9e9c5683bbf3, introduces an explicit identity validation mechanism at the beginning of the LinkSharing.ReadAll() method.
// Abstract representation of the patch logic in LinkSharing.ReadAll()
if _, isLinkShare := identity.(*LinkSharing); isLinkShare {
return nil, 0, ErrUnauthorized{}
}This modification strictly rejects any session where the authenticated entity is a *LinkSharing type, immediately terminating the listing process for link-share users regardless of their project-level read access. This effectively blocks the primary exploitation vector by preventing link-share tokens from interacting with the share-listing functionality entirely.
A subsequent commit, 5cd5dc409bfc807f79dac5e4ef4aec54b6efd6e2, further tightens the authorization logic by altering the project-level permission check within the same ReadAll() method. The check was upgraded from verifying Project.CanRead to requiring Project.IsAdmin. This change ensures that only users with explicit administrative privileges over the project, rather than mere view access, can enumerate the project's active shares and their corresponding hashes.
Complementing the backend patches, commit 74d1bddb3ab32fc8983d778bb65e89b1d50227d6 introduces a frontend mitigation. The user interface was updated to conditionally hide the link sharing management section from users lacking administrative permissions. While frontend hiding is not a primary security control, it reduces the visibility of the vulnerable functionality and establishes defense-in-depth by preventing legitimate low-privileged users from inadvertently discovering the endpoint.
Exploitation of CVE-2026-33680 requires an attacker to possess or obtain a valid read-only link share hash for a target project. These hashes are frequently distributed via public channels, embedded in documentation, or shared via email to grant stakeholders limited visibility into task progress. Once a hash is acquired, the attacker initiates the exploitation chain by authenticating against the link-share API endpoint.
The attacker sends a POST request to /api/v1/shares/READ_ONLY_HASH/auth. The Vikunja backend validates the hash and returns a JSON Web Token (JWT) representing the read-only session. This token is subsequently injected into the HTTP Authorization header as a Bearer token for all subsequent API requests.
curl -s -X POST http://<vikunja-instance>/api/v1/shares/<READ_ONLY_HASH>/auth | jq '.token'With a valid read-only JWT, the attacker targets the ReadAll endpoint for the project's shares. By executing a GET request to /api/v1/projects/<project_id>/shares, the attacker leverages the missing authorization check. The backend processes the request and returns an array of JSON objects representing every active share for the project.
curl -s -H "Authorization: Bearer <read-only-jwt>" \
http://<vikunja-instance>/api/v1/projects/<project_id>/shares | jq '.[].hash, .[].permission'The attacker parses the JSON response to identify shares with a permission level of 2, indicating administrative access. By extracting the corresponding Hash value from these objects, the attacker obtains an administrative token. The final step involves authenticating against the /auth endpoint using the newly acquired admin hash, resulting in the issuance of a JWT that grants complete administrative control over the project and its associated resources.
The impact of CVE-2026-33680 is categorized as high, primarily due to the severe confidentiality breach that leads directly to complete privilege escalation. The vulnerability is assigned a CVSS v3.1 base score of 7.5, reflecting a network-exploitable flaw that requires no special privileges or user interaction. The attack vector is strictly remote, and the complexity of exploitation is low.
The fundamental issue is the exposure of secret bearer tokens. In Vikunja's architecture, the link share hash functions as both an identifier and a password. Disclosing these hashes to unauthorized parties constitutes a total compromise of the link-sharing security model. An attacker gaining access to an administrative hash bypasses all intended access controls for the affected project.
Upon successfully escalating privileges using a leaked administrative hash, the attacker achieves comprehensive control over the project environment. While the CVSS vector strictly lists the impact as High for Confidentiality and None for Integrity and Availability, the indirect consequences of this disclosure are significant. An attacker operating with a compromised administrative token possesses the capability to arbitrarily modify project tasks, alter configurations, revoke access for legitimate users, or entirely delete the project and its associated data.
Despite the severity of the vulnerability, the Exploit Prediction Scoring System (EPSS) assigns it a score of 0.0003 (0.03%), placing it in the 8.51st percentile. This indicates a very low historical probability of imminent, widespread exploitation in the wild. The low probability is likely due to the prerequisite requirement of obtaining an initial read-only link share and the specific, targeted nature of self-hosted Vikunja deployments.
The vendor addressed the vulnerability in Vikunja version 2.2.2. Organizations operating self-hosted instances of Vikunja must prioritize updating to this version or a later release. The update replaces the vulnerable authorization logic and implements strict type checking to prevent link-share authenticated sessions from accessing the share listing endpoint.
Administrators should execute a comprehensive review of all active link shares across their projects. Because exploitation leaves minimal traces beyond standard API access logs, determining if a specific instance has been compromised requires careful log analysis. Security personnel should examine access logs for requests to the /api/v1/projects/*/shares endpoint originating from IP addresses associated with known link-share tokens, particularly if those requests are immediately followed by administrative authentication attempts.
If patching cannot be performed immediately, mitigation strategies are limited due to the structural nature of the vulnerability. Organizations can implement Web Application Firewall (WAF) rules to detect and block access to the /api/v1/projects/*/shares endpoint if the request includes a JWT associated with a link-share identity, although this requires advanced WAF configuration and deep packet inspection of the JWT payload.
As a precautionary measure, organizations that suspect unauthorized access or have operated vulnerable instances in untrusted environments should strongly consider revoking all existing link shares. Regenerating the shares and distributing new hashes will invalidate any tokens potentially acquired by attackers during the vulnerability window, ensuring that previously exposed administrative hashes are rendered useless.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Vikunja Vikunja | < 2.2.2 | - |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-285 |
| CVSS v3.1 | 7.5 (High) |
| Attack Vector | Network |
| Impact | High (Confidentiality, Integrity, Availability via Admin Escalation) |
| Exploit Status | Proof-of-Concept (PoC) available |
| EPSS Score | 0.03% (Percentile: 8.51%) |
Improper Authorization occurs when an application does not appropriately verify whether the user is authorized to access the requested resource.