mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-22 11:45:59 +01:00
[SG-458] Master Password security checks (browser) (#4502)
* work: add base logic for password lookup * work: added browser support for hibp * work: SG-558 combine weak + leak warning * fix: language stuff * fix: form values are neater tho :( * fix: no cast
This commit is contained in:
parent
ae3edcc34d
commit
497b08df44
@ -2046,5 +2046,35 @@
|
||||
},
|
||||
"rememberEmail": {
|
||||
"message": "Remember email"
|
||||
},
|
||||
"exposedMasterPassword": {
|
||||
"message": "Exposed Master Password"
|
||||
},
|
||||
"exposedMasterPasswordDesc": {
|
||||
"message": "Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?"
|
||||
},
|
||||
"weakAndExposedMasterPassword": {
|
||||
"message": "Weak and Exposed Master Password"
|
||||
},
|
||||
"weakAndBreachedMasterPasswordDesc": {
|
||||
"message": "Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?"
|
||||
},
|
||||
"checkForBreaches": {
|
||||
"message": "Check known data breaches for this password"
|
||||
},
|
||||
"important": {
|
||||
"message": "Important:"
|
||||
},
|
||||
"masterPasswordHint": {
|
||||
"message": "Your master password cannot be recovered if you forget it!"
|
||||
},
|
||||
"characterMinimum": {
|
||||
"message": "$LENGTH$ character minimum",
|
||||
"placeholders": {
|
||||
"length": {
|
||||
"content": "$1",
|
||||
"example": "14"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="masterPasswordHelp" class="box-footer">
|
||||
{{ "masterPassDesc" | i18n }}
|
||||
<b>{{ "important" | i18n }}</b> {{ "masterPasswordHint" | i18n }}
|
||||
{{ characterMinimumMessage }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
@ -107,6 +108,17 @@
|
||||
<div id="hintHelp" class="box-footer">
|
||||
{{ "masterPassHintDesc" | i18n }}
|
||||
</div>
|
||||
<div class="box-content row-top-padding">
|
||||
<div
|
||||
class="box-content-row box-content-row-checkbox box-content-row-checkbox-left box-content-row-word-break"
|
||||
appBoxRow
|
||||
>
|
||||
<input type="checkbox" id="checkForBreaches" formControlName="checkForBreaches" />
|
||||
<label for="checkForBreaches">
|
||||
{{ "checkForBreaches" | i18n }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div [hidden]="!showCaptcha()"><iframe id="hcaptcha_iframe" height="80"></iframe></div>
|
||||
<div class="box last" *ngIf="showTerms">
|
||||
|
@ -4,6 +4,7 @@ import { Router } from "@angular/router";
|
||||
|
||||
import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/components/register.component";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { AuthService } from "@bitwarden/common/abstractions/auth.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
|
||||
@ -34,7 +35,8 @@ export class RegisterComponent extends BaseRegisterComponent {
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
passwordGenerationService: PasswordGenerationService,
|
||||
environmentService: EnvironmentService,
|
||||
logService: LogService
|
||||
logService: LogService,
|
||||
auditService: AuditService
|
||||
) {
|
||||
super(
|
||||
formValidationErrorService,
|
||||
@ -48,7 +50,8 @@ export class RegisterComponent extends BaseRegisterComponent {
|
||||
platformUtilsService,
|
||||
passwordGenerationService,
|
||||
environmentService,
|
||||
logService
|
||||
logService,
|
||||
auditService
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,10 @@
|
||||
padding-bottom: 10px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
&.row-top-padding {
|
||||
padding-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.box-footer {
|
||||
|
@ -4,6 +4,7 @@ import { Router } from "@angular/router";
|
||||
|
||||
import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/components/register.component";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { AuthService } from "@bitwarden/common/abstractions/auth.service";
|
||||
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
@ -36,7 +37,8 @@ export class RegisterComponent extends BaseRegisterComponent implements OnInit,
|
||||
environmentService: EnvironmentService,
|
||||
private broadcasterService: BroadcasterService,
|
||||
private ngZone: NgZone,
|
||||
logService: LogService
|
||||
logService: LogService,
|
||||
auditService: AuditService
|
||||
) {
|
||||
super(
|
||||
formValidationErrorService,
|
||||
@ -50,7 +52,8 @@ export class RegisterComponent extends BaseRegisterComponent implements OnInit,
|
||||
platformUtilsService,
|
||||
passwordGenerationService,
|
||||
environmentService,
|
||||
logService
|
||||
logService,
|
||||
auditService
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import { Router } from "@angular/router";
|
||||
|
||||
import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/components/register.component";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { AuthService } from "@bitwarden/common/abstractions/auth.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
|
||||
@ -41,7 +42,8 @@ export class RegisterFormComponent extends BaseRegisterComponent {
|
||||
passwordGenerationService: PasswordGenerationService,
|
||||
private policyService: PolicyService,
|
||||
environmentService: EnvironmentService,
|
||||
logService: LogService
|
||||
logService: LogService,
|
||||
auditService: AuditService
|
||||
) {
|
||||
super(
|
||||
formValidationErrorService,
|
||||
@ -55,7 +57,8 @@ export class RegisterFormComponent extends BaseRegisterComponent {
|
||||
platformUtilsService,
|
||||
passwordGenerationService,
|
||||
environmentService,
|
||||
logService
|
||||
logService,
|
||||
auditService
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { AbstractControl, UntypedFormBuilder, ValidatorFn, Validators } from "@a
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { AuthService } from "@bitwarden/common/abstractions/auth.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
|
||||
@ -38,6 +39,8 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
|
||||
showTerms = true;
|
||||
showErrorSummary = false;
|
||||
passwordStrengthResult: any;
|
||||
characterMinimumMessage: string;
|
||||
minimumLength = 8;
|
||||
color: string;
|
||||
text: string;
|
||||
|
||||
@ -45,8 +48,8 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
|
||||
{
|
||||
email: ["", [Validators.required, Validators.email]],
|
||||
name: [""],
|
||||
masterPassword: ["", [Validators.required, Validators.minLength(8)]],
|
||||
confirmMasterPassword: ["", [Validators.required, Validators.minLength(8)]],
|
||||
masterPassword: ["", [Validators.required, Validators.minLength(this.minimumLength)]],
|
||||
confirmMasterPassword: ["", [Validators.required, Validators.minLength(this.minimumLength)]],
|
||||
hint: [
|
||||
null,
|
||||
[
|
||||
@ -56,6 +59,7 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
|
||||
),
|
||||
],
|
||||
],
|
||||
checkForBreaches: [false],
|
||||
acceptPolicies: [false, [this.acceptPoliciesValidation()]],
|
||||
},
|
||||
{
|
||||
@ -85,10 +89,12 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
protected passwordGenerationService: PasswordGenerationService,
|
||||
environmentService: EnvironmentService,
|
||||
protected logService: LogService
|
||||
protected logService: LogService,
|
||||
protected auditService: AuditService
|
||||
) {
|
||||
super(environmentService, i18nService, platformUtilsService);
|
||||
this.showTerms = !platformUtilsService.isSelfHost();
|
||||
this.characterMinimumMessage = this.i18nService.t("characterMinimum", this.minimumLength);
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
@ -212,7 +218,24 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
|
||||
return { isValid: false };
|
||||
}
|
||||
|
||||
if (this.passwordStrengthResult != null && this.passwordStrengthResult.score < 3) {
|
||||
const passwordWeak =
|
||||
this.passwordStrengthResult != null && this.passwordStrengthResult.score < 3;
|
||||
const passwordLeak =
|
||||
this.formGroup.controls.checkForBreaches.value &&
|
||||
(await this.auditService.passwordLeaked(this.formGroup.controls.masterPassword.value)) > 0;
|
||||
|
||||
if (passwordWeak && passwordLeak) {
|
||||
const result = await this.platformUtilsService.showDialog(
|
||||
this.i18nService.t("weakAndBreachedMasterPasswordDesc"),
|
||||
this.i18nService.t("weakAndExposedMasterPassword"),
|
||||
this.i18nService.t("yes"),
|
||||
this.i18nService.t("no"),
|
||||
"warning"
|
||||
);
|
||||
if (!result) {
|
||||
return { isValid: false };
|
||||
}
|
||||
} else if (passwordWeak) {
|
||||
const result = await this.platformUtilsService.showDialog(
|
||||
this.i18nService.t("weakMasterPasswordDesc"),
|
||||
this.i18nService.t("weakMasterPassword"),
|
||||
@ -223,7 +246,19 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
|
||||
if (!result) {
|
||||
return { isValid: false };
|
||||
}
|
||||
} else if (passwordLeak) {
|
||||
const result = await this.platformUtilsService.showDialog(
|
||||
this.i18nService.t("exposedMasterPasswordDesc"),
|
||||
this.i18nService.t("exposedMasterPassword"),
|
||||
this.i18nService.t("yes"),
|
||||
this.i18nService.t("no"),
|
||||
"warning"
|
||||
);
|
||||
if (!result) {
|
||||
return { isValid: false };
|
||||
}
|
||||
}
|
||||
|
||||
return { isValid: true };
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user