PM-8197 Do not allow browser biometric for locked account (#9216)

Process reload is the means by which we protect user keys in memory. once an account locks, it triggers a process reload (assuming no other accounts are unlocked), that frees renderer memory.

However, if the user is not unlocked, it is not protected by the process reload, so we may keep user keys in memory.
This commit is contained in:
Matt Gibson 2024-05-17 08:54:19 -04:00 committed by GitHub
parent 9db2495de3
commit 7819dbdd56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 1 deletions

View File

@ -1714,6 +1714,12 @@
"biometricsNotSupportedDesc": {
"message": "Browser biometrics is not supported on this device."
},
"biometricsNotUnlockedTitle": {
"message": "User locked or logged out"
},
"biometricsNotUnlockedDesc": {
"message": "Please unlock this user in the desktop application and try again."
},
"biometricsFailedTitle": {
"message": "Biometrics failed"
},

View File

@ -321,6 +321,15 @@ export class NativeMessagingBackground {
type: "danger",
});
break;
} else if (message.response === "not unlocked") {
this.messagingService.send("showDialog", {
title: { key: "biometricsNotUnlockedTitle" },
content: { key: "biometricsNotUnlockedDesc" },
acceptButtonText: { key: "ok" },
cancelButtonText: null,
type: "danger",
});
break;
} else if (message.response === "canceled") {
break;
}

View File

@ -1,8 +1,10 @@
import { Injectable, NgZone } from "@angular/core";
import { firstValueFrom } from "rxjs";
import { firstValueFrom, map } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { MasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@ -43,6 +45,7 @@ export class NativeMessagingService {
private nativeMessageHandler: NativeMessageHandlerService,
private dialogService: DialogService,
private accountService: AccountService,
private authService: AuthService,
private ngZone: NgZone,
) {}
@ -137,6 +140,19 @@ export class NativeMessagingService {
return this.send({ command: "biometricUnlock", response: "not supported" }, appId);
}
const userId =
(message.userId as UserId) ??
(await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id))));
if (userId == null) {
return this.send({ command: "biometricUnlock", response: "not unlocked" }, appId);
}
const authStatus = await firstValueFrom(this.authService.authStatusFor$(userId));
if (authStatus !== AuthenticationStatus.Unlocked) {
return this.send({ command: "biometricUnlock", response: "not unlocked" }, appId);
}
const biometricUnlockPromise =
message.userId == null
? firstValueFrom(this.biometricStateService.biometricUnlockEnabled$)