From 91a936e07d2976d4246dfe834281c3aaa87f9503 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sun, 18 Jan 2026 20:13:25 +0200 Subject: [PATCH] Security Fix 13: LinkedBoardActivitiesBleed. Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7. --- server/publications/activities.js | 47 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/server/publications/activities.js b/server/publications/activities.js index 1243a07f3..8c3e17d69 100644 --- a/server/publications/activities.js +++ b/server/publications/activities.js @@ -21,37 +21,38 @@ Meteor.publish('activities', function(kind, id, limit, showActivities) { return this.ready(); } - // Check user permissions - only BoardAdmin can view activities - if (this.userId) { - const user = ReactiveCache.getUser(this.userId); - const board = ReactiveCache.getBoard(id); - - if (user && board) { - // Find user membership in board - const membership = board.members.find(m => m.userId === this.userId); - - // Only BoardAdmin can view activities - if (!membership || !membership.isAdmin) { - return this.ready(); - } - } else { - // If board or user not found, deny - return this.ready(); - } - } else { - // If not logged in, deny + if (!this.userId) { return this.ready(); } - // Get linkedBoard let linkedElmtId = [id]; - if (kind == 'board') { + let board; + + if (kind === 'board') { + board = ReactiveCache.getBoard(id); + if (!board || !board.isVisibleBy(this.userId)) { + return this.ready(); + } + + // Get linked boards, but only those visible to the user ReactiveCache.getCards({ "type": "cardType-linkedBoard", - "boardId": id} - ).forEach(card => { + "boardId": id + }).forEach(card => { + const linkedBoard = ReactiveCache.getBoard(card.linkedId); + if (linkedBoard && linkedBoard.isVisibleBy(this.userId)) { linkedElmtId.push(card.linkedId); + } }); + } else if (kind === 'card') { + const card = ReactiveCache.getCard(id); + if (!card) { + return this.ready(); + } + board = ReactiveCache.getBoard(card.boardId); + if (!board || !board.isVisibleBy(this.userId)) { + return this.ready(); + } } const selector = showActivities