Skip to content

Commit

Permalink
Exclude explicit new password fields from field match ratio calculation
Browse files Browse the repository at this point in the history
This helps users change passwords on well written websites without
increasing the risk of auto-fill into irrelevant form fields.
We want the overall match for the form to still be lower though, so
that we can still fill in the sign-in form in preference to the
change-password form in the unlikely event they are both presented on
the same page.
  • Loading branch information
luckyrat committed Jul 13, 2020
1 parent ecfcaaa commit 1234dbc
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
14 changes: 13 additions & 1 deletion common/model/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ export class Field {
name: element.name,
id: element.id,
type: domType,
labels
labels,
autocompleteValues: collectAutocompleteValues(element)
})
],
value,
Expand Down Expand Up @@ -240,3 +241,14 @@ function collectLabels(element: HTMLInputElement | HTMLSelectElement) {
});
return labels.length ? labels : undefined;
}

function collectAutocompleteValues(element: HTMLInputElement | HTMLSelectElement) {
const values: string[] = [];
element.autocomplete
?.trim()
.split(" ")
.forEach(v => {
if (v) values.push(v);
});
return values.length ? values : undefined;
}
4 changes: 4 additions & 0 deletions common/model/Locator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ export class Locator {
// Visible and accessibility labels
labels?: string[];

// Any autocomplete values we found, or require, in the DOM
autocompleteValues?: string[];

constructor(locator: Partial<Locator>) {
this.id = locator.id || "";
this.name = locator.name || "";
this.type = locator.type || "";
this.query = locator.query;
this.labels = locator.labels;
this.autocompleteValues = locator.autocompleteValues;
}

//TODO:4: Things like MaxLength that can be used to both help identify the field and generate new values/passwords
Expand Down
30 changes: 22 additions & 8 deletions page/formFilling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1710,8 +1710,22 @@ export class FormFilling {
for (let i = 0; i < matchedFields.length; i++) {
let mostRelevantScore = 0;
const formField = matchedFields[i].field;

if (
formField.locators[0].autocompleteValues?.some(
v => v.toLowerCase() === "new-password"
)
) {
// Record as a successful match for the purposes of match ratio calculations
// if this is a new password field as part of a change password form. So we
// don't affect the selection of the form or entry to fill but when all
// else is equal, we will have a higher chance of auto-filling the existing
// user name and password fields.
fieldMatchSuccesses[i] = true;
}

for (let j = 0; j < entryFields.length; j++) {
const fmscore = this.calculateFieldMatchScore(
const fmScore = this.calculateFieldMatchScore(
matchedFields[i],
entryFields[j],
currentPage,
Expand All @@ -1728,24 +1742,24 @@ export class FormFilling {
" (id: " +
formField.locators[0].id +
") is " +
fmscore
fmScore
);
if (fmscore > mostRelevantScore) {
mostRelevantScore = fmscore;
if (fmScore > mostRelevantScore) {
mostRelevantScore = fmScore;
}
const fmscoreForRatio = fmscore - (visibleFieldMap[i] ? 35 : 0);
const fmScoreForRatio = fmScore - (visibleFieldMap[i] ? 35 : 0);
if (
fmscoreForRatio >= minFieldRelevance &&
fmScoreForRatio >= minFieldRelevance &&
entryFields[j].value &&
!fieldMatchSuccesses[i]
) {
fieldMatchSuccesses[i] = true;
}
if (
matchedFields[i].highestScore == null ||
fmscore > matchedFields[i].highestScore
fmScore > matchedFields[i].highestScore
) {
matchedFields[i].highestScore = fmscore;
matchedFields[i].highestScore = fmScore;
}
}
totalRelevanceScore += mostRelevantScore;
Expand Down

0 comments on commit 1234dbc

Please sign in to comment.