CVE-2026-58660 Overview
CVE-2026-58660 is an Insecure Direct Object Reference (IDOR) vulnerability in Kanboard through version 1.2.52. The flaw resides in the BoardAjaxController::save() method, which powers the kanban drag-and-drop endpoint. The controller validates the caller's role against the attacker-supplied project_id but never confirms that the submitted task_id actually belongs to that project. Because task identifiers are sequential integers shared across the entire instance, any authenticated user with membership in a single project can enumerate and relocate tasks from any other project, including private ones. The issue is tracked as [CWE-639: Authorization Bypass Through User-Controlled Key].
Critical Impact
Authenticated users can corrupt, hide, or move tasks in projects they have no membership in, breaking task integrity across the entire Kanboard instance.
Affected Products
- Kanboard versions through 1.2.52
- Kanboard instances prior to commit 564cc30e1e360959572e01e158734d9475c05903
- All multi-tenant Kanboard deployments hosting private projects
Discovery Timeline
- 2026-07-15 - CVE-2026-58660 published to NVD
- 2026-07-15 - Last updated in NVD database
Technical Details for CVE-2026-58660
Vulnerability Analysis
The vulnerable code path handles AJAX requests when a user drags a task card between columns on a Kanboard board. The controller reads project_id and task_id from the JSON request body. It then invokes a role check against the supplied project_id through projectRole->canMoveTask(). That check confirms the caller can move tasks within the specified project, but it makes no assertion about which project the task_id actually belongs to. An attacker who is a member of any project can supply their own project_id for the role check while providing a task_id referencing a completely unrelated project. The server accepts the mismatch and performs the move.
Root Cause
The root cause is a missing cross-object ownership validation between the two request parameters. Task identifiers in Kanboard are auto-incrementing integers that are globally unique across the instance rather than scoped to a project. This makes enumeration trivial. Without a lookup verifying that taskFinderModel->getProjectId($task_id) matches the supplied project_id, the authorization logic collapses into a permission check on an attacker-controlled context.
Attack Vector
An authenticated attacker sends a crafted JSON payload to the board drag-and-drop endpoint. The payload contains a project_id corresponding to a project where the attacker holds a role, along with a task_id belonging to a private or unrelated project. The attacker can iterate through sequential integers to discover valid tasks and move them into columns of the attacker-controlled project, effectively hiding or corrupting them from their legitimate owners.
// Patch applied in app/Controller/BoardAjaxController.php
$values = $this->request->getJson();
+ if ($this->taskFinderModel->getProjectId($values['task_id']) !== $project_id) {
+ throw new AccessForbiddenException(e("You don't have the permission to move this task"));
+ }
+
if (! $this->helper->projectRole->canMoveTask($project_id, $values['src_column_id'], $values['dst_column_id'])) {
throw new AccessForbiddenException(e("You don't have the permission to move this task"));
}
Source: Kanboard commit 564cc30. The patch adds an explicit ownership check comparing the task's actual project to the request's project_id before authorization proceeds.
Detection Methods for CVE-2026-58660
Indicators of Compromise
- Unexpected task movements in the Kanboard project_activities and task_has_events audit tables originating from users who lack membership in the affected project
- HTTP POST requests to the board AJAX endpoint (?controller=BoardAjaxController&action=save) where the JSON body's task_id does not belong to the referenced project_id
- Tasks appearing under columns of projects they were never created in
Detection Strategies
- Correlate web server access logs with Kanboard audit events to flag drag-and-drop operations executed by users lacking a role on the task's original project
- Alert on rapid, sequential task_id access patterns from a single session, which suggests enumeration
- Compare tasks.project_id history against activity records to detect tasks that changed project ownership without an authorized moveTaskToAnotherProject event
Monitoring Recommendations
- Enable Kanboard's built-in activity stream and forward logs to a centralized logging platform for retention and query
- Monitor authentication logs for low-privilege accounts issuing unusually high volumes of board AJAX calls
- Establish a baseline of legitimate task-move activity per user and alert on outliers
How to Mitigate CVE-2026-58660
Immediate Actions Required
- Upgrade Kanboard to a release containing commit 564cc30e1e360959572e01e158734d9475c05903 or apply the patch directly to app/Controller/BoardAjaxController.php
- Audit the tasks and project_activities tables for unauthorized task movements since the vulnerability was introduced
- Rotate API tokens for any user accounts suspected of abusing the endpoint
Patch Information
The fix is available in the upstream repository via Kanboard commit 564cc30. Additional context is available in the Kanboard issue #5852, the pull request #5853, and the VulnCheck advisory. Administrators should deploy a Kanboard build that includes this commit as soon as testing permits.
Workarounds
- Restrict Kanboard access to trusted users only until the patch is applied, since exploitation requires an authenticated account
- Place the application behind a reverse proxy that inspects JSON payloads to the board AJAX endpoint and rejects requests where request context suggests cross-project references
- Temporarily disable the drag-and-drop board feature by removing user roles that grant task-move privileges on shared instances
# Apply the upstream patch to an existing Kanboard installation
cd /var/www/kanboard
git fetch origin
git cherry-pick 564cc30e1e360959572e01e158734d9475c05903
# Or pull the latest release tag that includes the fix
git checkout <fixed-release-tag>
php -l app/Controller/BoardAjaxController.php
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

