diff --git a/apps/nestjs-backend/src/features/auth/local-auth/local-auth.service.ts b/apps/nestjs-backend/src/features/auth/local-auth/local-auth.service.ts index ceb338606f..666e52ca50 100644 --- a/apps/nestjs-backend/src/features/auth/local-auth/local-auth.service.ts +++ b/apps/nestjs-backend/src/features/auth/local-auth/local-auth.service.ts @@ -6,6 +6,7 @@ import { PrismaService } from '@teable/db-main-prisma'; import { EmailVerifyCodeType, MailTransporterType, MailType } from '@teable/openapi'; import type { IChangePasswordRo, IInviteWaitlistVo, ISignup } from '@teable/openapi'; import * as bcrypt from 'bcrypt'; +import { timingSafeEqual } from 'crypto'; import { isEmpty } from 'lodash'; import ms from 'ms'; import { ClsService } from 'nestjs-cls'; @@ -62,7 +63,14 @@ export class LocalAuthService { salt: string | null ) { const _hashPassword = await bcrypt.hash(password || '', salt || ''); - return _hashPassword === hashPassword; + if (!_hashPassword || !hashPassword) { + return false; + } + try { + return timingSafeEqual(Buffer.from(_hashPassword), Buffer.from(hashPassword)); + } catch { + return false; + } } private async getUserByIdOrThrow(userId: string) { diff --git a/apps/nestjs-backend/src/features/auth/permission.service.ts b/apps/nestjs-backend/src/features/auth/permission.service.ts index 9c899d1d01..557db3f129 100644 --- a/apps/nestjs-backend/src/features/auth/permission.service.ts +++ b/apps/nestjs-backend/src/features/auth/permission.service.ts @@ -10,6 +10,7 @@ import { } from '@teable/core'; import { PrismaService } from '@teable/db-main-prisma'; import { CollaboratorType } from '@teable/openapi'; +import { timingSafeEqual } from 'crypto'; import { intersection, union } from 'lodash'; import { ClsService } from 'nestjs-cls'; import { CustomHttpException, TemplateAppTokenNotAllowedException } from '../../custom.exception'; @@ -580,7 +581,14 @@ export class PermissionService { if (!baseShare?.password) { return false; } - return payload.password === baseShare.password; + try { + return timingSafeEqual( + Buffer.from(payload.password), + Buffer.from(baseShare.password) + ); + } catch { + return false; + } } catch { return false; }