CVE-2023-33970 (published 2023-06-05T20:15Z)

Kanboard is open source project management software that focuses on the Kanban methodology. A vulnerability related to a `missing access control` was found, which allows a User with the lowest privileges to leak all the tasks and projects titles within the software, even if they are not invited or it's a personal project. This could also lead to private/critical information being leaked if such information is in the title. This issue has been addressed in version 1.2.30. Users are advised to upgrade. There are no known workarounds for this vulnerability.\n

CVSS v3 base score: 6.5, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-862
cwe_name: Missing Authorization
description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
extended_description: 
            Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
            When access control checks are not applied, users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
         
         

Fix information:
repo_url: https://github.com/kanboard/kanboard
commit_details: repo_url: https://github.com/kanboard/kanboard
author: Frédéric Guillot
author_date: 2023-05-29 19:39:28-07:00
msg: Add missing permission check when creating/updating internal links
repository: repo_url: https://github.com/kanboard/kanboard
repo_name: kanboard/kanboard
description: Kanban project management software
repo_language: PHP
owner: kanboard
file_changes: filename: TaskLinkProcedure.php
change_type: ModificationType.MODIFY
diff: @@ -51,6 +51,15 @@ class TaskLinkProcedure extends BaseProcedure
     public function createTaskLink($task_id, $opposite_task_id, $link_id)
     {
         TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTaskLink', $task_id);
+
+        if ($this->userSession->isLogged()) {
+            $opposite_task = $this->taskFinderModel->getById($opposite_task_id);
+
+            if (! $this->projectPermissionModel->isUserAllowed($opposite_task['project_id'], $this->userSession->getId())) {
+                return false;
+            }
+        }
+
         return $this->taskLinkModel->create($task_id, $opposite_task_id, $link_id);
     }
 
@@ -67,6 +76,15 @@ class TaskLinkProcedure extends BaseProcedure
     public function updateTaskLink($task_link_id, $task_id, $opposite_task_id, $link_id)
     {
         TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTaskLink', $task_id);
+
+        if ($this->userSession->isLogged()) {
+            $opposite_task = $this->taskFinderModel->getById($opposite_task_id);
+
+            if (! $this->projectPermissionModel->isUserAllowed($opposite_task['project_id'], $this->userSession->getId())) {
+                return false;
+            }
+        }
+
         return $this->taskLinkModel->update($task_link_id, $task_id, $opposite_task_id, $link_id);
     }
 

programming_language: PHP
filename: TaskInternalLinkController.php
change_type: ModificationType.MODIFY
diff: @@ -2,6 +2,7 @@
 
 namespace Kanboard\Controller;
 
+use Kanboard\Core\Controller\AccessForbiddenException;
 use Kanboard\Core\Controller\PageNotFoundException;
 
 /**
@@ -53,6 +54,12 @@ class TaskInternalLinkController extends BaseController
         list($valid, $errors) = $this->taskLinkValidator->validateCreation($values);
 
         if ($valid) {
+            $opposite_task = $this->taskFinderModel->getById($values['opposite_task_id']);
+
+            if (! $this->projectPermissionModel->isUserAllowed($opposite_task['project_id'], $this->userSession->getId())) {
+                throw new AccessForbiddenException();
+            }
+
             if ($this->taskLinkModel->create($values['task_id'], $values['opposite_task_id'], $values['link_id']) !== false) {
                 $this->flash->success(t('Link added successfully.'));
 
@@ -121,6 +128,12 @@ class TaskInternalLinkController extends BaseController
         list($valid, $errors) = $this->taskLinkValidator->validateModification($values);
 
         if ($valid) {
+            $opposite_task = $this->taskFinderModel->getById($values['opposite_task_id']);
+
+            if (! $this->projectPermissionModel->isUserAllowed($opposite_task['project_id'], $this->userSession->getId())) {
+                throw new AccessForbiddenException();
+            }
+
             if ($this->taskLinkModel->update($values['id'], $values['task_id'], $values['opposite_task_id'], $values['link_id'])) {
                 $this->flash->success(t('Link updated successfully.'));
                 return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'])).'#links');

programming_language: PHP