Skip to content

Commit 4044c2a

Browse files
authored
Consider more user inputs when calculating zxcvbn score (matrix-org#11180)
* Consider more user inputs when calculating zxcvbn score * MatrixClientPeg.getHomeserverName may throw
1 parent 90e65e8 commit 4044c2a

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

src/components/views/auth/PassphraseField.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ interface IProps extends Omit<IInputProps, "onValidate" | "element"> {
3131
minScore: 0 | 1 | 2 | 3 | 4;
3232
value: string;
3333
fieldRef?: RefCallback<Field> | RefObject<Field>;
34+
// Additional strings such as a username used to catch bad passwords
35+
userInputs?: string[];
3436

3537
label: string;
3638
labelEnterPassword: string;
@@ -57,7 +59,7 @@ class PassphraseField extends PureComponent<IProps> {
5759
deriveData: async ({ value }): Promise<zxcvbn.ZXCVBNResult | null> => {
5860
if (!value) return null;
5961
const { scorePassword } = await import("../../../utils/PasswordScorer");
60-
return scorePassword(MatrixClientPeg.get(), value);
62+
return scorePassword(MatrixClientPeg.get(), value, this.props.userInputs);
6163
},
6264
rules: [
6365
{

src/components/views/auth/RegistrationForm.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
473473
value={this.state.password}
474474
onChange={this.onPasswordChange}
475475
onValidate={this.onPasswordValidate}
476+
userInputs={[this.state.username]}
476477
/>
477478
);
478479
}

src/utils/PasswordScorer.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import zxcvbn, { ZXCVBNFeedbackWarning } from "zxcvbn";
1818
import { MatrixClient } from "matrix-js-sdk/src/matrix";
1919

2020
import { _t, _td } from "../languageHandler";
21+
import { MatrixClientPeg } from "../MatrixClientPeg";
2122

2223
const ZXCVBN_USER_INPUTS = ["riot", "matrix"];
2324

@@ -59,20 +60,32 @@ _td("Short keyboard patterns are easy to guess");
5960
*
6061
* @param {string} password Password to score
6162
* @param matrixClient the client of the logged in user, if any
63+
* @param userInputs additional strings such as the user's name which should be considered a bad password component
6264
* @returns {object} Score result with `score` and `feedback` properties
6365
*/
64-
export function scorePassword(matrixClient: MatrixClient | null, password: string): zxcvbn.ZXCVBNResult | null {
66+
export function scorePassword(
67+
matrixClient: MatrixClient | null,
68+
password: string,
69+
userInputs: string[] = [],
70+
): zxcvbn.ZXCVBNResult | null {
6571
if (password.length === 0) return null;
6672

67-
const userInputs = ZXCVBN_USER_INPUTS.slice();
73+
const inputs = [...userInputs, ...ZXCVBN_USER_INPUTS];
6874
if (matrixClient) {
69-
userInputs.push(matrixClient.getUserIdLocalpart()!);
75+
inputs.push(matrixClient.getUserIdLocalpart()!);
7076
}
7177

72-
let zxcvbnResult = zxcvbn(password, userInputs);
78+
try {
79+
const domain = MatrixClientPeg.getHomeserverName();
80+
inputs.push(domain);
81+
} catch {
82+
// This is fine
83+
}
84+
85+
let zxcvbnResult = zxcvbn(password, inputs);
7386
// Work around https://github.com/dropbox/zxcvbn/issues/216
7487
if (password.includes(" ")) {
75-
const resultNoSpaces = zxcvbn(password.replace(/ /g, ""), userInputs);
88+
const resultNoSpaces = zxcvbn(password.replace(/ /g, ""), inputs);
7689
if (resultNoSpaces.score < zxcvbnResult.score) zxcvbnResult = resultNoSpaces;
7790
}
7891

0 commit comments

Comments
 (0)