Security Fix 4: MigrationBleed.

Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
This commit is contained in:
Lauri Ojansivu 2026-01-18 19:24:07 +02:00
parent 251d49eea9
commit cc35dafef5

View file

@ -248,14 +248,14 @@ class ComprehensiveBoardMigration {
// Step 6: Fix avatar URLs
updateProgress('fix_avatar_urls', 0, 'Fixing avatar URLs...');
results.steps.fixAvatarUrls = await this.fixAvatarUrls(boardId);
results.steps.fixAvatarUrls = await this.fixAvatarUrls();
updateProgress('fix_avatar_urls', 100, 'Avatar URLs fixed', {
avatarsFixed: results.steps.fixAvatarUrls.avatarsFixed
});
// Step 8: Fix attachment URLs
updateProgress('fix_attachment_urls', 0, 'Fixing attachment URLs...');
results.steps.fixAttachmentUrls = await this.fixAttachmentUrls(boardId);
results.steps.fixAttachmentUrls = await this.fixAttachmentUrls();
updateProgress('fix_attachment_urls', 100, 'Attachment URLs fixed', {
attachmentsFixed: results.steps.fixAttachmentUrls.attachmentsFixed
});
@ -554,7 +554,7 @@ class ComprehensiveBoardMigration {
/**
* Step 7: Fix avatar URLs (remove problematic auth parameters and fix URL formats)
*/
async fixAvatarUrls(boardId) {
async fixAvatarUrls() {
const users = ReactiveCache.getUsers({});
let avatarsFixed = 0;
@ -609,7 +609,7 @@ class ComprehensiveBoardMigration {
/**
* Step 8: Fix attachment URLs (remove problematic auth parameters and fix URL formats)
*/
async fixAttachmentUrls(boardId) {
async fixAttachmentUrls() {
const attachments = ReactiveCache.getAttachments({});
let attachmentsFixed = 0;
@ -722,6 +722,19 @@ Meteor.methods({
throw new Meteor.Error('not-authorized');
}
const user = ReactiveCache.getUser(this.userId);
const board = ReactiveCache.getBoard(boardId);
if (!board) {
throw new Meteor.Error('board-not-found');
}
const isBoardAdmin = board.hasAdmin(this.userId);
const isInstanceAdmin = user && user.isAdmin;
if (!isBoardAdmin && !isInstanceAdmin) {
throw new Meteor.Error('not-authorized', 'You must be a board admin or instance admin to perform this action.');
}
return comprehensiveBoardMigration.executeMigration(boardId);
},
@ -745,13 +758,29 @@ Meteor.methods({
return comprehensiveBoardMigration.detectMigrationIssues(boardId);
},
'comprehensiveBoardMigration.fixAvatarUrls'(boardId) {
check(boardId, String);
'comprehensiveBoardMigration.fixAvatarUrls'() {
if (!this.userId) {
throw new Meteor.Error('not-authorized');
}
return comprehensiveBoardMigration.fixAvatarUrls(boardId);
const user = ReactiveCache.getUser(this.userId);
if (!user || !user.isAdmin) {
throw new Meteor.Error('not-authorized', 'Only instance admins can perform this action.');
}
return comprehensiveBoardMigration.fixAvatarUrls();
},
'comprehensiveBoardMigration.fixAttachmentUrls'() {
if (!this.userId) {
throw new Meteor.Error('not-authorized');
}
const user = ReactiveCache.getUser(this.userId);
if (!user || !user.isAdmin) {
throw new Meteor.Error('not-authorized', 'Only instance admins can perform this action.');
}
return comprehensiveBoardMigration.fixAttachmentUrls();
}
});