From 02c97f7985b3ae9f017b10ac75107f07d298de0a Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 9 Feb 2024 13:42:19 +0000 Subject: [PATCH] fix actual security problems #407 timing attacks on HTTP signature and backup codes for 2fa --- packages/backend/src/core/UserAuthService.ts | 5 ++++- packages/backend/src/server/ActivityPubServerService.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/core/UserAuthService.ts b/packages/backend/src/core/UserAuthService.ts index ccf4dfc6b..9d6c8ce63 100644 --- a/packages/backend/src/core/UserAuthService.ts +++ b/packages/backend/src/core/UserAuthService.ts @@ -11,6 +11,7 @@ import type { MiUserProfile, UserProfilesRepository, UsersRepository } from '@/m import { bindThis } from '@/decorators.js'; import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js'; import type { MiLocalUser } from '@/models/User.js'; +import * as crypto from 'node:crypto'; @Injectable() export class UserAuthService { @@ -27,7 +28,9 @@ export class UserAuthService { public async twoFactorAuthenticate(profile: MiUserProfile, token: string): Promise { if (profile.twoFactorBackupSecret?.includes(token)) { await this.userProfilesRepository.update({ userId: profile.userId }, { - twoFactorBackupSecret: profile.twoFactorBackupSecret.filter((secret) => secret !== token), + twoFactorBackupSecret: profile.twoFactorBackupSecret.filter( + (secret) => !crypto.timingSafeEqual(secret, token) + ), }); } else { const delta = OTPAuth.TOTP.validate({ diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index b1562a95f..e67848482 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -287,7 +287,7 @@ export class ActivityPubServerService { const hash = crypto.createHash('sha256').update(request.rawBody).digest('base64'); - if (hash !== digestValue) { + if (! crypto.timingSafeEqual(hash, digestValue)) { // Invalid digest reply.code(401); return;