[PM-5938] Prevent vault coruption on key-rotation on desycned vault (#9235)

* Prevent key-rotation when local vault is desynced

* Prevent key-rotation on non-decrypted vault

* Remove cipher check that is done on server side
This commit is contained in:
Bernd Schoolmann 2024-05-30 11:08:47 +02:00 committed by GitHub
parent fb7273beb8
commit 6d0ef65094
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 12 additions and 0 deletions

View File

@ -17,6 +17,7 @@ import { UserId } from "@bitwarden/common/types/guid";
import { UserKey } from "@bitwarden/common/types/key"; import { UserKey } from "@bitwarden/common/types/key";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { CipherType } from "@bitwarden/common/vault/enums/cipher-type"; import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
import { Folder } from "@bitwarden/common/vault/models/domain/folder"; import { Folder } from "@bitwarden/common/vault/models/domain/folder";
@ -49,6 +50,7 @@ describe("KeyRotationService", () => {
let mockStateService: MockProxy<StateService>; let mockStateService: MockProxy<StateService>;
let mockConfigService: MockProxy<ConfigService>; let mockConfigService: MockProxy<ConfigService>;
let mockKdfConfigService: MockProxy<KdfConfigService>; let mockKdfConfigService: MockProxy<KdfConfigService>;
let mockSyncService: MockProxy<SyncService>;
const mockUserId = Utils.newGuid() as UserId; const mockUserId = Utils.newGuid() as UserId;
const mockAccountService: FakeAccountService = mockAccountServiceWith(mockUserId); const mockAccountService: FakeAccountService = mockAccountServiceWith(mockUserId);
@ -68,6 +70,7 @@ describe("KeyRotationService", () => {
mockStateService = mock<StateService>(); mockStateService = mock<StateService>();
mockConfigService = mock<ConfigService>(); mockConfigService = mock<ConfigService>();
mockKdfConfigService = mock<KdfConfigService>(); mockKdfConfigService = mock<KdfConfigService>();
mockSyncService = mock<SyncService>();
keyRotationService = new UserKeyRotationService( keyRotationService = new UserKeyRotationService(
mockMasterPasswordService, mockMasterPasswordService,
@ -83,6 +86,7 @@ describe("KeyRotationService", () => {
mockStateService, mockStateService,
mockAccountService, mockAccountService,
mockKdfConfigService, mockKdfConfigService,
mockSyncService,
); );
}); });

View File

@ -13,6 +13,7 @@ import { SendService } from "@bitwarden/common/tools/send/services/send.service.
import { UserKey } from "@bitwarden/common/types/key"; import { UserKey } from "@bitwarden/common/types/key";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { CipherWithIdRequest } from "@bitwarden/common/vault/models/request/cipher-with-id.request"; import { CipherWithIdRequest } from "@bitwarden/common/vault/models/request/cipher-with-id.request";
import { FolderWithIdRequest } from "@bitwarden/common/vault/models/request/folder-with-id.request"; import { FolderWithIdRequest } from "@bitwarden/common/vault/models/request/folder-with-id.request";
@ -38,6 +39,7 @@ export class UserKeyRotationService {
private stateService: StateService, private stateService: StateService,
private accountService: AccountService, private accountService: AccountService,
private kdfConfigService: KdfConfigService, private kdfConfigService: KdfConfigService,
private syncService: SyncService,
) {} ) {}
/** /**
@ -49,6 +51,12 @@ export class UserKeyRotationService {
throw new Error("Invalid master password"); throw new Error("Invalid master password");
} }
if ((await this.syncService.getLastSync()) === null) {
throw new Error(
"The local vault is de-synced and the keys cannot be rotated. Please log out and log back in to resolve this issue.",
);
}
// Create master key to validate the master password // Create master key to validate the master password
const masterKey = await this.cryptoService.makeMasterKey( const masterKey = await this.cryptoService.makeMasterKey(
masterPassword, masterPassword,