CVE-2026-91985
Executive Summary
CVE-2026-91985 is an information-disclosure and privilege-escalation vulnerability in the Vikunja task-management platform affecting versions before 2.6.0. Single-share read endpoints fail to restrict access to the link-share hash field, allowing low-privileged (read-only) members to retrieve the secret credential that protects a link-share. Once disclosed, that hash can be exchanged for a link-share JWT carrying the share's permission level, enabling unauthorized writes and administrative actions. Because the flaw is remotely reachable and requires no user interaction, unauthenticated or low-privilege attackers against exposed instances should be treated as a live risk.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Vikunja is a self-hosted, open-source todo/task application. It supports "link shares" — shareable links that grant access to a project or list at a defined permission level (e.g., read-only). Each link share is protected by a secret value, referred to in the NVD description as the link-share hash, which functions as the credential used to prove entitlement when the link is used. Internally, this hash is exchanged for a link-share JWT that carries the share's permissions.
The defect, CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor), is that Vikunja before 2.6.0 "fails to properly restrict access to the link-share hash field in single-share read endpoints." In other words, there exists an endpoint whose purpose is to read a single link share (metadata such as its ID, permission level, and settings). That response object also serializes the hash field — the secret credential — instead of omitting or masking it. Any caller who can reach the single-share read endpoint, including a read-only member, receives the hash in the API response.
This is fundamentally a broken-access-control / excessive-data-exposure issue, not an injection or memory-safety bug. The trust boundary being violated is "secret material must never be returned to any caller through a read endpoint." Note that CVSS scores the confidentiality impact as High (C:H) and availability as None (A:N); the NVD text additionally describes downstream integrity/privilege impact because the stolen secret is usable as a credential. The declared vector (PR:N) reflects that the endpoint can be reached without privileged authentication in the vulnerable configuration.
The critical mechanic is the trust relationship between the hash and the JWT: the hash is not merely informational metadata — it is the exchange token. Disclosing it is equivalent to disclosing a password. The NVD description states that attackers "can exchange the disclosed hash for a link-share JWT at the share's permission level." Thus the disclosure converts an otherwise read-only principal into a principal whose effective permissions equal the share's permission level, which may be higher than the attacker's own membership role. If the link share was created with write or admin-level permissions, the attacker inherits them.
No public proof-of-concept, Nuclei template, or exploit code is available (PoC/Exploit: None). The precise endpoint path, authentication requirement, and response schema are not enumerated in the provided data; per accuracy constraints, specific route names, parameter names, and code identifiers beyond the hash field are not asserted here. The attack chain below is therefore described at the vulnerability-class level.
Exploitation Scenarios
Because no public PoC exists, the chain below is inferred from the vulnerability class (CWE-200 credential disclosure via an over-permissive read endpoint) and the NVD description only.
Reconnaissance / target identification. An attacker locates an internet-exposed Vikunja instance. This may be an unauthenticated external actor scanning for self-hosted Vikunja deployments, or an authenticated low-privilege "read-only member" who legitimately belongs to a project but should not be able to escalate. The attacker enumerates link shares visible to their account (e.g., those shared into a project they can read).
Triggering the flaw. The attacker invokes the "single-share read" endpoint that returns a specific link share's properties. Because the endpoint fails to restrict access to the
hashfield, the response includes the share's secrethashalongside the expected metadata. No exploit payload is required — the disclosure is the result of a normal, legitimate read request that happens to over-return a sensitive field. This is consistent with CWE-200 and with the NVD statement that read-only members can "obtain the share's secret credential."Credential exchange. The attacker takes the disclosed
hashand presents it to the mechanism that converts a share hash into an authenticated session — the NVD states the hash can be "exchange[d] … for a link-share JWT at the share's permission level." The resulting JWT is issued with the share's permission level, not the attacker's own.Post-exploitation impact. Holding a share-level JWT, the attacker performs actions permitted to that share. If the share was configured for write or administrative capability, the attacker can perform "unauthorized writes or administrative actions" — modifying tasks/projects, altering share settings, or other state-changing operations. The original read-only restriction is fully bypassed. The confidentiality loss (hash disclosure) is a prerequisite that yields integrity and privilege impact.
Constraints and caveats: whether the single-share read endpoint is reachable unauthenticated or only by an authenticated read-only member depends on deployment configuration and is not specified in the provided data. The declared CVSS vector (PR:N, UI:N) indicates the flaw can be reached without prior privilege in the scored scenario, but PR:N should be validated against the specific deployment (public vs. private membership). No evidence of in-the-wild exploitation, scanning, or named threat-actor campaigns exists in the available data.
Impact Assessment
The primary scored impact is confidentiality: CVSS C:H reflects full disclosure of the link-share credential. CVSS base score 7.5 (High) with vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N indicates the vulnerability is network-reachable, low-complexity, requires no privileges or user interaction, and is scoped to the vulnerable component. Note that the scored vector does not itself tally integrity impact; the integrity/administrative consequences described in the NVD text stem from using the disclosed secret as a credential and may raise real-world risk above the base score for shares configured with write/admin rights.
Blast radius: any Vikunja instance before 2.6.0, especially self-hosted deployments exposed to untrusted networks. Because link shares are commonly used to give external collaborators partial access, a single overly broad share can expose an entire project. Affected parties include organizations using Vikunja for project/task tracking where shared links carry write or admin permissions. Business impact includes unauthorized modification of task/project data, potential tampering with share configurations, and loss of integrity trust in the platform. There is no availability impact per the vector; exploitation is silent and does not crash or degrade the service, which favors stealthy abuse.
Detection Guidance
Sigma Rule
title: Vikunja Link-Share Hash Disclosure Attempt (CVE-2026-91985)
id: 3b9f1c2a-7d4e-4a51-9c0e-1f2a3b4c5d6e
status: experimental
description: Detects access to Vikunja single-share read endpoints that may return the link-share secret hash, followed by hash-to-JWT exchange behavior.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-91985
author: valtersit.com
date: 2026-01-01
logsource:
category: web
product: vikunja
detection:
selection_path:
cs-uri-stem|contains:
- '/shares/'
- '/link-share'
- '/shares/'
selection_method:
cs-method:
- 'GET'
selection_response_field:
# detect responses that include the sensitive hash field
cs-uri-query|contains: 'hash'
condition: selection_path and selection_method
fields:
- c-ip
- cs-uri-stem
- sc-status
falsepositives:
- Legitimate share owners reading their own share metadata
level: medium
YARA Rule
rule CVE_2026_91985_Vikunja_LinkShare_Hash
{
meta:
author = "valtersit.com"
description = "Detects Vikunja API responses or artifacts leaking the link-share hash field (CVE-2026-91985)"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-91985"
date = "2026-01-01"
strings:
$json_hash = "\"hash\":" ascii nocase
$share_kw = "link" ascii nocase
$share_kw2 = "share" ascii nocase
$jwt = "eyJ" ascii
condition:
$json_hash and ( $share_kw or $share_kw2 ) and filesize < 1MB
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-91985 Vikunja link-share hash disclosure attempt"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"/shares/"; nocase; http.uri; content:"hash"; nocase; classtype:attempted-recon; reference:cve,2026-91985; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-91985; sid:9198526; rev:1;)
Elastic Detection
sequence by source.ip with maxspan=1m
[ network where http.request.method == "GET" and
http.request.path : "/shares/*" ]
[ network where http.request.method == "GET" and
http.request.path : "*hash*" ]
Splunk SPL Query
index=web sourcetype=vikunja OR sourcetype=access_combined
| search uri_path="*shares*" OR uri="*link-share*"
| eval suspicious_hash_exposure=if(match(_raw,"(?i)\"hash\"\s*:"),1,0)
| where suspicious_hash_exposure=1 OR status=200
| stats count min(_time) as first_seen max(_time) as last_seen by src_ip, uri_path, status
| where count >= 1
| sort - count
Wazuh OSSEC Rule
<group name="vikunja,cve-2026-91985,">
<rule id="919852" level="10">
<decoded_as>json</decoded_as>
<field name="uri">\.shares\.|link-share</field>
<field name="method">GET</field>
<description>CVE-2026-91985: Possible Vikunja link-share hash disclosure attempt via single-share read endpoint</description>
<mitre>
<id>T1190</id>
</mitre>
<group>web,accesslog,</group>
</rule>
<rule id="919853" level="12">
<decoded_as>json</decoded_as>
<field name="uri">\.shares\.|link-share</field>
<regex>"hash"\s*:\s*"[A-Za-z0-9]{8,}"</regex>
<description>CVE-2026-91985: Vikunja response appears to serialize link-share hash credential</description>
<mitre>
<id>T1190</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 2/4 (CLAIMED — single source claims patch (not independently confirmed)).
- Immediate mitigations (in the absence of confirmed patching):
- Upgrade to Vikunja 2.6.0 or later, which the single OSV source claims fixes the field-restriction issue; validate the fix independently because patch confidence is only 2/4.
- If upgrading is not immediately possible, restrict network access to the Vikunja API so untrusted callers cannot reach single-share read endpoints; place the instance behind an authenticated reverse proxy or VPN.
- Audit existing link shares and, where possible, rotate/recreate any whose secret hash may have been exposed. Remove or down-scope link shares configured with write or administrative permissions.
- Reduce membership scope so that read-only members cannot enumerate shares that carry elevated permissions.
- Patch/upgrade steps:
- Confirm the installed version (
< 2.6.0is vulnerable) and back up the database and configuration before upgrading. - Deploy Vikunja 2.6.0+ per the project's upgrade guidance, then verify that single-share read responses no longer include the
hashfield. - Because the patch report is single-source/unofficial in this dataset, treat the fix as unverified until the upstream project confirms it.
- Long-term hardening:
- Adopt output allow-listing for API serializers so secret fields (such as link-share hashes) are never returned by default.
- Treat link-share hashes as credentials: store hashed, rotate on demand, and never expose in read responses or logs.
- Enforce least privilege on link-share permission levels and review them periodically.
- Add API regression tests asserting that secret fields are absent from all read endpoints.
- Monitor logs for repeated single-share reads and unusual hash-to-JWT exchanges (see Detection Guidance).
References
- NVD — CVE-2026-91985: https://nvd.nist.gov/vuln/detail/CVE-2026-91985
- OSV (single-source patch claim): https://osv.dev/ (search CVE-2026-91985)
- Vikunja project / releases (upgrade source): https://vikunja.io
- CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor: https://cwe.mitre.org/data/definitions/200.html
- MITRE ATT&CK T1190 — Exploit Public-Facing Application: https://attack.mitre.org/techniques/T1190/
Threat-actor note: No named threat-actor campaigns, exploit-in-the-wild evidence, PoC, Nuclei template, or ExploitDB code were identified in the provided data. CVE-2026-91985 is not listed in CISA KEV, and no EPSS score is available from FIRST.org at this time.