mirror of
https://github.com/wekan/wekan.git
synced 2026-01-23 17:56:09 +01:00
Security Fix 8: MoveStorageBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
This commit is contained in:
parent
053bf1dfb7
commit
c413a7e860
1 changed files with 54 additions and 2 deletions
|
|
@ -259,7 +259,26 @@ if (Meteor.isServer) {
|
|||
check(fileObjId, String);
|
||||
check(storageDestination, String);
|
||||
|
||||
if (!this.userId) {
|
||||
throw new Meteor.Error('not-authorized', 'You must be logged in.');
|
||||
}
|
||||
|
||||
const fileObj = ReactiveCache.getAttachment(fileObjId);
|
||||
if (!fileObj) {
|
||||
throw new Meteor.Error('attachment-not-found', 'Attachment not found');
|
||||
}
|
||||
|
||||
const board = ReactiveCache.getBoard(fileObj.boardId);
|
||||
if (!board || !board.isVisibleBy({ _id: this.userId })) {
|
||||
throw new Meteor.Error('not-authorized', 'You do not have access to this board.');
|
||||
}
|
||||
|
||||
// Allowlist storage destinations
|
||||
const allowedDestinations = ['fs', 'gridfs', 's3'];
|
||||
if (!allowedDestinations.includes(storageDestination)) {
|
||||
throw new Meteor.Error('invalid-storage-destination', 'Invalid storage destination');
|
||||
}
|
||||
|
||||
moveToStorage(fileObj, storageDestination, fileStoreStrategyFactory);
|
||||
},
|
||||
renameAttachment(fileObjId, newName) {
|
||||
|
|
@ -294,7 +313,20 @@ if (Meteor.isServer) {
|
|||
validateAttachment(fileObjId) {
|
||||
check(fileObjId, String);
|
||||
|
||||
if (!this.userId) {
|
||||
throw new Meteor.Error('not-authorized', 'You must be logged in.');
|
||||
}
|
||||
|
||||
const fileObj = ReactiveCache.getAttachment(fileObjId);
|
||||
if (!fileObj) {
|
||||
throw new Meteor.Error('attachment-not-found', 'Attachment not found');
|
||||
}
|
||||
|
||||
const board = ReactiveCache.getBoard(fileObj.boardId);
|
||||
if (!board || !board.isVisibleBy({ _id: this.userId })) {
|
||||
throw new Meteor.Error('not-authorized', 'You do not have access to this board.');
|
||||
}
|
||||
|
||||
const isValid = Promise.await(isFileValid(fileObj, attachmentUploadMimeTypes, attachmentUploadSize, attachmentUploadExternalProgram));
|
||||
|
||||
if (!isValid) {
|
||||
|
|
@ -305,11 +337,31 @@ if (Meteor.isServer) {
|
|||
check(fileObjId, String);
|
||||
check(storageDestination, String);
|
||||
|
||||
Meteor.call('validateAttachment', fileObjId);
|
||||
if (!this.userId) {
|
||||
throw new Meteor.Error('not-authorized', 'You must be logged in.');
|
||||
}
|
||||
|
||||
const fileObj = ReactiveCache.getAttachment(fileObjId);
|
||||
if (!fileObj) {
|
||||
throw new Meteor.Error('attachment-not-found', 'Attachment not found');
|
||||
}
|
||||
|
||||
if (fileObj) {
|
||||
const board = ReactiveCache.getBoard(fileObj.boardId);
|
||||
if (!board || !board.isVisibleBy({ _id: this.userId })) {
|
||||
throw new Meteor.Error('not-authorized', 'You do not have access to this board.');
|
||||
}
|
||||
|
||||
// Allowlist storage destinations
|
||||
const allowedDestinations = ['fs', 'gridfs', 's3'];
|
||||
if (!allowedDestinations.includes(storageDestination)) {
|
||||
throw new Meteor.Error('invalid-storage-destination', 'Invalid storage destination');
|
||||
}
|
||||
|
||||
Meteor.call('validateAttachment', fileObjId);
|
||||
|
||||
const fileObjAfter = ReactiveCache.getAttachment(fileObjId);
|
||||
|
||||
if (fileObjAfter) {
|
||||
Meteor.defer(() => Meteor.call('moveAttachmentToStorage', fileObjId, storageDestination));
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue