From 5b5a1f08e1caf13d7c8ae5a1aeb01da35078e6c6 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Tue, 21 Oct 2025 19:24:43 +0900 Subject: [PATCH] =?UTF-8?q?enhance(backend):=20=E7=AE=A1=E7=90=86=E8=80=85?= =?UTF-8?q?/=E3=83=A2=E3=83=87=E3=83=AC=E3=83=BC=E3=82=BF=E3=83=BC?= =?UTF-8?q?=E3=81=AF=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=AE=E3=82=A2?= =?UTF-8?q?=E3=83=83=E3=83=97=E3=83=AD=E3=83=BC=E3=83=89=E5=88=B6=E9=99=90?= =?UTF-8?q?=E3=82=92=E3=83=90=E3=82=A4=E3=83=91=E3=82=B9=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve #16687 --- CHANGELOG.md | 1 + packages/backend/src/core/DriveService.ts | 59 ++++++++++++----------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59172bfd57..46356ac754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - Fix: 投票が終了した後に投票結果が正しく表示されない問題を修正 ### Server +- Enhance: 管理者/モデレーターはファイルのアップロード制限をバイパスするように - Enhance: セキュリティの向上 ## 2025.10.0 diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 567bad2a2d..816f83ec93 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -517,40 +517,43 @@ export class DriveService { this.registerLogger.debug(`ADD DRIVE FILE: user ${user?.id ?? 'not set'}, name ${detectedName}, tmp ${path}`); //#region Check drive usage and mime type - if (user && !isLink) { + if (user != null && !isLink) { const isLocalUser = this.userEntityService.isLocalUser(user); - const policies = await this.roleService.getUserPolicies(user.id); + const isModerator = isLocalUser ? await this.roleService.isModerator(user) : false; + if (!isModerator) { + const policies = await this.roleService.getUserPolicies(user.id); - const allowedMimeTypes = policies.uploadableFileTypes; - const isAllowed = allowedMimeTypes.some((mimeType) => { - if (mimeType === '*' || mimeType === '*/*') return true; - if (mimeType.endsWith('/*')) return info.type.mime.startsWith(mimeType.slice(0, -1)); - return info.type.mime === mimeType; - }); - if (!isAllowed) { - throw new IdentifiableError('bd71c601-f9b0-4808-9137-a330647ced9b', `Unallowed file type: ${info.type.mime}`); - } - - const driveCapacity = 1024 * 1024 * policies.driveCapacityMb; - const maxFileSize = 1024 * 1024 * policies.maxFileSizeMb; - - if (maxFileSize < info.size) { - if (isLocalUser) { - throw new IdentifiableError('f9e4e5f3-4df4-40b5-b400-f236945f7073', 'Max file size exceeded.'); + const allowedMimeTypes = policies.uploadableFileTypes; + const isAllowed = allowedMimeTypes.some((mimeType) => { + if (mimeType === '*' || mimeType === '*/*') return true; + if (mimeType.endsWith('/*')) return info.type.mime.startsWith(mimeType.slice(0, -1)); + return info.type.mime === mimeType; + }); + if (!isAllowed) { + throw new IdentifiableError('bd71c601-f9b0-4808-9137-a330647ced9b', `Unallowed file type: ${info.type.mime}`); } - } - const usage = await this.driveFileEntityService.calcDriveUsageOf(user); + const driveCapacity = 1024 * 1024 * policies.driveCapacityMb; + const maxFileSize = 1024 * 1024 * policies.maxFileSizeMb; - this.registerLogger.debug('drive capacity override applied'); - this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`); - - // If usage limit exceeded - if (driveCapacity < usage + info.size) { - if (isLocalUser) { - throw new IdentifiableError('c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6', 'No free space.'); + if (maxFileSize < info.size) { + if (isLocalUser) { + throw new IdentifiableError('f9e4e5f3-4df4-40b5-b400-f236945f7073', 'Max file size exceeded.'); + } + } + + const usage = await this.driveFileEntityService.calcDriveUsageOf(user); + + this.registerLogger.debug('drive capacity override applied'); + this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`); + + // If usage limit exceeded + if (driveCapacity < usage + info.size) { + if (isLocalUser) { + throw new IdentifiableError('c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6', 'No free space.'); + } + await this.expireOldFile(await this.usersRepository.findOneByOrFail({ id: user.id }) as MiRemoteUser, driveCapacity - info.size); } - await this.expireOldFile(await this.usersRepository.findOneByOrFail({ id: user.id }) as MiRemoteUser, driveCapacity - info.size); } } //#endregion