From 7b63146d98324735e6a57ddeb4e856fc1df87e75 Mon Sep 17 00:00:00 2001 From: Chocolate Pie <106949016+chocolate-pie@users.noreply.github.com> Date: Wed, 7 Jun 2023 11:00:56 +0900 Subject: [PATCH] Fix Vulnerability --- packages/backend/src/server/api/ApiCallService.ts | 2 +- packages/backend/src/server/api/endpoint-base.ts | 9 +++++---- packages/backend/src/server/api/endpoints/app/show.ts | 4 ++-- .../src/server/api/endpoints/drive/files/create.ts | 2 +- .../server/api/endpoints/drive/files/upload-from-url.ts | 2 +- packages/backend/src/server/api/endpoints/i.ts | 4 ++-- packages/backend/src/server/api/endpoints/i/update.ts | 4 ++-- packages/backend/src/server/api/endpoints/users/show.ts | 2 +- 8 files changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/backend/src/server/api/ApiCallService.ts b/packages/backend/src/server/api/ApiCallService.ts index e94259d014..a9d750f351 100644 --- a/packages/backend/src/server/api/ApiCallService.ts +++ b/packages/backend/src/server/api/ApiCallService.ts @@ -341,7 +341,7 @@ export class ApiCallService implements OnApplicationShutdown { } // API invoking - return await ep.exec(data, user, token, file, request.ip, request.headers).catch((err: Error) => { + return await ep.exec(data, user, token, flashToken, file, request.ip, request.headers).catch((err: Error) => { if (err instanceof ApiError || err instanceof AuthenticationError) { throw err; } else { diff --git a/packages/backend/src/server/api/endpoint-base.ts b/packages/backend/src/server/api/endpoint-base.ts index 1555a3ca46..5aae602c00 100644 --- a/packages/backend/src/server/api/endpoint-base.ts +++ b/packages/backend/src/server/api/endpoint-base.ts @@ -3,6 +3,7 @@ import Ajv from 'ajv'; import type { Schema, SchemaType } from '@/misc/json-schema.js'; import type { LocalUser } from '@/models/entities/User.js'; import type { AccessToken } from '@/models/entities/AccessToken.js'; +import type { FlashToken } from '@/misc/flash-token.js'; import { ApiError } from './error.js'; import type { IEndpointMeta } from './endpoints.js'; @@ -21,16 +22,16 @@ type File = { // TODO: paramsの型をT['params']のスキーマ定義から推論する type Executor = - (params: SchemaType, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, cleanup?: () => any, ip?: string | null, headers?: Record | null) => + (params: SchemaType, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, flashToken: FlashToken | null, file?: File, cleanup?: () => any, ip?: string | null, headers?: Record | null) => Promise>>; export abstract class Endpoint { - public exec: (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, ip?: string | null, headers?: Record | null) => Promise; + public exec: (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, flashToken: FlashToken | null, file?: File, ip?: string | null, headers?: Record | null) => Promise; constructor(meta: T, paramDef: Ps, cb: Executor) { const validate = ajv.compile(paramDef); - this.exec = (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, ip?: string | null, headers?: Record | null) => { + this.exec = (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, flashToken: FlashToken | null, file?: File, ip?: string | null, headers?: Record | null) => { let cleanup: undefined | (() => void) = undefined; if (meta.requireFile) { @@ -61,7 +62,7 @@ export abstract class Endpoint { return Promise.reject(err); } - return cb(params as SchemaType, user, token, file, cleanup, ip, headers); + return cb(params as SchemaType, user, token, flashToken, file, cleanup, ip, headers); }; } } diff --git a/packages/backend/src/server/api/endpoints/app/show.ts b/packages/backend/src/server/api/endpoints/app/show.ts index eaafa8dc1b..52e9c02aba 100644 --- a/packages/backend/src/server/api/endpoints/app/show.ts +++ b/packages/backend/src/server/api/endpoints/app/show.ts @@ -40,8 +40,8 @@ export default class extends Endpoint { private appEntityService: AppEntityService, ) { - super(meta, paramDef, async (ps, user, token) => { - const isSecure = user != null && token == null; + super(meta, paramDef, async (ps, user, token, flashToken) => { + const isSecure = user != null && token == null && flashToken == null; // Lookup app const ap = await this.appsRepository.findOneBy({ id: ps.appId }); diff --git a/packages/backend/src/server/api/endpoints/drive/files/create.ts b/packages/backend/src/server/api/endpoints/drive/files/create.ts index a1c1f9325e..e128e80944 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/create.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/create.ts @@ -78,7 +78,7 @@ export default class extends Endpoint { private metaService: MetaService, private driveService: DriveService, ) { - super(meta, paramDef, async (ps, me, _, file, cleanup, ip, headers) => { + super(meta, paramDef, async (ps, me, _1, _2, file, cleanup, ip, headers) => { // Get 'name' parameter let name = ps.name ?? file!.name ?? null; if (name != null) { diff --git a/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts b/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts index c835587c4a..4edc4cdc9f 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts @@ -48,7 +48,7 @@ export default class extends Endpoint { private driveService: DriveService, private globalEventService: GlobalEventService, ) { - super(meta, paramDef, async (ps, user, _1, _2, _3, ip, headers) => { + super(meta, paramDef, async (ps, user, _1, _2, _3, _4, ip, headers) => { this.driveService.uploadFromUrl({ url: ps.url, user, folderId: ps.folderId, sensitive: ps.isSensitive, force: ps.force, comment: ps.comment, requestIp: ip, requestHeaders: headers }).then(file => { this.driveFileEntityService.pack(file, { self: true }).then(packedFile => { this.globalEventService.publishMainStream(user.id, 'urlUploadFinished', { diff --git a/packages/backend/src/server/api/endpoints/i.ts b/packages/backend/src/server/api/endpoints/i.ts index a3e3e02a12..f336caeb77 100644 --- a/packages/backend/src/server/api/endpoints/i.ts +++ b/packages/backend/src/server/api/endpoints/i.ts @@ -44,8 +44,8 @@ export default class extends Endpoint { private userEntityService: UserEntityService, ) { - super(meta, paramDef, async (ps, user, token) => { - const isSecure = token == null; + super(meta, paramDef, async (ps, user, token, flashToken) => { + const isSecure = token == null && flashToken == null; const now = new Date(); const today = `${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()}`; diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 8f5e6177c2..5f4bc8cf3f 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -194,9 +194,9 @@ export default class extends Endpoint { private roleService: RoleService, private cacheService: CacheService, ) { - super(meta, paramDef, async (ps, _user, token) => { + super(meta, paramDef, async (ps, _user, token, flashToken) => { const user = await this.usersRepository.findOneByOrFail({ id: _user.id }); - const isSecure = token == null; + const isSecure = token == null && flashToken == null; const updates = {} as Partial; const profileUpdates = {} as Partial; diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts index ba432c273b..ed42c66de8 100644 --- a/packages/backend/src/server/api/endpoints/users/show.ts +++ b/packages/backend/src/server/api/endpoints/users/show.ts @@ -87,7 +87,7 @@ export default class extends Endpoint { private perUserPvChart: PerUserPvChart, private apiLoggerService: ApiLoggerService, ) { - super(meta, paramDef, async (ps, me, _1, _2, _3, ip) => { + super(meta, paramDef, async (ps, me, _1, _2, _3, _4, ip) => { let user; const isModerator = await this.roleService.isModerator(me);