Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/fluent-boards/app/Http/Controllers/BoardController.php
+++ b/fluent-boards/app/Http/Controllers/BoardController.php
@@ -968,7 +968,7 @@
public function archiveAllTasksInStage($board_id, $stage_id)
{
- $updates = $this->stageService->archiveAllTasksInStage($stage_id);
+ $updates = $this->stageService->archiveAllTasksInStage($stage_id, $board_id);
return [
'message' => __('Tasks have been archived', 'fluent-boards'),
'updatedTasks' => $updates,
--- a/fluent-boards/app/Http/Controllers/CommentController.php
+++ b/fluent-boards/app/Http/Controllers/CommentController.php
@@ -27,7 +27,10 @@
public function getComments(Request $request, $board_id, $task_id)
{
+ $board_id = absint($board_id);
+ $task_id = absint($task_id);
try {
+ Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$filter = $request->getSafe('filter', 'sanitize_text_field');
$per_page = 10;
@@ -105,7 +108,7 @@
$usersToSendEmail = [];
if ($comment->type == 'reply') {
- $parentComment = Comment::findOrFail($comment->parent_id);
+ $parentComment = Comment::where('board_id', (int) $board_id)->where('id', $comment->parent_id)->firstOrFail();
$commenterId = $parentComment->created_by;
if ($commenterId != get_current_user_id())
{
@@ -212,7 +215,10 @@
public function deleteComment($board_id, $comment_id)
{
+ $board_id = absint($board_id);
+ $comment_id = absint($comment_id);
try {
+ Comment::where('board_id', $board_id)->where('id', $comment_id)->firstOrFail();
$this->commentService->delete($comment_id);
return $this->sendSuccess([
@@ -261,7 +267,10 @@
public function deleteReply($board_id, $reply_id)
{
+ $board_id = absint($board_id);
+ $reply_id = absint($reply_id);
try {
+ Comment::where('board_id', $board_id)->where('id', $reply_id)->firstOrFail();
$this->commentService->deleteReply($reply_id);
return $this->sendSuccess([
@@ -330,7 +339,9 @@
public function updateCommentPrivacy($board_id, $comment_id)
{
- $comment = Comment::findOrFail($comment_id);
+ $board_id = absint($board_id);
+ $comment_id = absint($comment_id);
+ $comment = Comment::where('board_id', $board_id)->where('id', $comment_id)->firstOrFail();
// Check if user has permission to update the comment
if ($comment->created_by != get_current_user_id()) {
--- a/fluent-boards/app/Http/Controllers/TaskController.php
+++ b/fluent-boards/app/Http/Controllers/TaskController.php
@@ -185,10 +185,10 @@
$stageService = new StageService();
- $task = Task::findOrFail($task_id);
+ $task = Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
- if (isset($task->parent_id)) {
- $task = Task::findOrFail($task->parent_id);
+ if ($task->parent_id) {
+ $task = Task::where('board_id', $board_id)->where('id', $task->parent_id)->firstOrFail();
}
if(!$task) {
@@ -239,6 +239,7 @@
{
$board_id = absint($board_id);
$task_id = absint($task_id);
+ Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$filter = $request->getSafe('filter', 'sanitize_text_field');
$per_page = 15; // Apparently, let's use a fixed number of items per page.
@@ -439,7 +440,7 @@
}
$validatedData = $this->updateTaskPropValidationAndSanitation($col, $value);
- $task = Task::with(['board', 'labels', 'assignees'])->findOrFail($task_id);
+ $task = Task::with(['board', 'labels', 'assignees'])->where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$oldDateValue = null;
if (in_array($col, ['due_at', 'started_at'])) {
@@ -488,7 +489,7 @@
{
$board_id = absint($board_id);
$task_id = absint($task_id);
- $task = Task::findOrFail($task_id);
+ $task = Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
// Capture old dates before updating
$oldDates = [
@@ -556,6 +557,7 @@
{
$board_id = absint($board_id);
$task_id = absint($task_id);
+ Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$integrationType = $request->getSafe('integrationType', 'sanitize_text_field');
return [
'message' => __('Task status has been updated', 'fluent-boards'),
@@ -567,7 +569,7 @@
{
$board_id = absint($board_id);
$task_id = absint($task_id);
- $task = Task::findOrFail($task_id);
+ $task = Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$options = null;
//if we need to do something before a task is deleted
do_action('fluent_boards/before_task_deleted', $task, $options);
@@ -698,6 +700,7 @@
{
$board_id = absint($board_id);
$task_id = absint($task_id);
+ Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$task = $this->taskService->moveTaskToNextStage($task_id);
return [
@@ -712,7 +715,7 @@
{
$board_id = absint($board_id);
$task_id = absint($task_id);
- $task = Task::findOrFail($task_id);
+ $task = Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$oldStageId = $task->stage_id;
$newStageId = $request->getSafe('newStageId', 'intval');
$newIndex = $request->getSafe('newIndex', 'intval');
@@ -779,6 +782,7 @@
{
$board_id = absint($board_id);
$task_id = absint($task_id);
+ Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
try {
// Pagination parameters
$page = $request->getSafe('page', 'intval', 1);
@@ -821,6 +825,7 @@
{
$board_id = absint($board_id);
$task_id = absint($task_id);
+ Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
try {
@@ -872,6 +877,7 @@
{
$board_id = absint($board_id);
$task_id = absint($task_id);
+ Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
try {
$file = Arr::get($request->files(), 'file')->toArray();
@@ -889,7 +895,7 @@
$fileUploadedData->save();
}
- $task = Task::find($task_id);
+ $task = Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$settings = $task->settings;
$this->taskService->deleteTaskCoverImage($settings);
$publicUrl = (new CommentService())->createPublicUrl($fileUploadedData, $board_id);
@@ -916,7 +922,7 @@
$board_id = absint($board_id);
$task_id = absint($task_id);
try {
- $task = Task::find($task_id);
+ $task = Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$settings = $task->settings;
$this->taskService->deleteTaskCoverImage($settings);
unset($settings['cover']);
@@ -1133,6 +1139,7 @@
'comment' => 'required',
]);
try {
+ Task::where('board_id', $board_id)->where('id', $task_id)->firstOrFail();
$taskData = fluent_boards_string_to_bool($taskData);
$clonedTask = $this->taskService->cloneTask($task_id, $taskData);
--- a/fluent-boards/app/Services/BoardService.php
+++ b/fluent-boards/app/Services/BoardService.php
@@ -708,9 +708,14 @@
->get();
}
- public function deleteInvitation($invitationId)
+ public function deleteInvitation($invitationId, $boardId = null)
{
- Meta::findOrFail($invitationId)->delete();
+ $query = Meta::query();
+ if ($boardId) {
+ $query->where('object_id', $boardId)
+ ->where('object_type', Constant::OBJECT_TYPE_BOARD);
+ }
+ $query->findOrFail($invitationId)->delete();
}
public function hasDataChanged($boardId)
--- a/fluent-boards/app/Services/StageService.php
+++ b/fluent-boards/app/Services/StageService.php
@@ -275,9 +275,13 @@
$board->save();
}
- public function updateStageTemplate($stage_id)
+ public function updateStageTemplate($stage_id, $boardId = null)
{
- $stage = Stage::findOrFail($stage_id);
+ $query = Stage::query();
+ if ($boardId) {
+ $query->where('board_id', $boardId);
+ }
+ $stage = $query->findOrFail($stage_id);
$stageSettings = $stage->settings;
if($stageSettings && array_key_exists('is_template', $stageSettings))
{
@@ -321,9 +325,13 @@
}
return $tasks;
}
- public function archiveAllTasksInStage($stage_id)
+ public function archiveAllTasksInStage($stage_id, $boardId = null)
{
- $tasks = Task::where('stage_id', $stage_id)->whereNull('parent_id')->whereNull('archived_at')->get();
+ $query = Task::where('stage_id', $stage_id)->whereNull('parent_id')->whereNull('archived_at');
+ if ($boardId) {
+ $query->where('board_id', $boardId);
+ }
+ $tasks = $query->get();
foreach ($tasks as $task) {
$task->position = 0;
$task->archived_at = current_time('mysql');
--- a/fluent-boards/fluent-boards.php
+++ b/fluent-boards/fluent-boards.php
@@ -5,7 +5,7 @@
/*
Plugin Name: Fluent Boards - Project Management Tool
Description: Fluent Boards is a powerful tool designed for efficient management of to-do lists, projects, and tasks with kanban board and more..
-Version: 1.91.2
+Version: 1.91.3
Author: WPManageNinja
Author URI: https://fluentboards.com
Plugin URI: https://fluentboards.com
@@ -20,7 +20,7 @@
}
define('FLUENT_BOARDS', 'fluent-boards');
-define('FLUENT_BOARDS_PLUGIN_VERSION', '1.91.2');
+define('FLUENT_BOARDS_PLUGIN_VERSION', '1.91.3');
define('FLUENT_BOARDS_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('FLUENT_BOARDS_DIR_FILE', __FILE__);
define('FLUENT_BOARDS_PLUGIN_URL', plugin_dir_url(__FILE__));