mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-05-18 21:40:41 -04:00
Add browser extension false-positive field exclusion logic (#1935)
This commit is contained in:
committed by
Leendert de Borst
parent
e6e4dbb6d6
commit
545cce0802
@@ -44,6 +44,13 @@ export type EmailVerificationPatterns = {
|
||||
changeEmail: RegExp[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Type for field exclusion patterns. These patterns are used to exclude fields from autofill detection.
|
||||
* Fields matching these patterns should not trigger the autofill popup, even if they match
|
||||
* other field patterns (like username or email).
|
||||
*/
|
||||
export type FieldExclusionPatterns = string[];
|
||||
|
||||
/**
|
||||
* English field patterns to detect English form fields.
|
||||
*/
|
||||
@@ -100,6 +107,16 @@ export const EnglishEmailVerificationPatterns: EmailVerificationPatterns = {
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* English field exclusion patterns. These patterns identify fields that should NOT trigger autofill,
|
||||
* such as search boxes and filters. These are commonly found in admin panels,
|
||||
* data tables, and navigation areas where autofill would be inappropriate.
|
||||
*/
|
||||
export const EnglishFieldExclusionPatterns: FieldExclusionPatterns = [
|
||||
'search', 'find', 'lookup', 'searchbox', 'search-box', 'searchfield', 'search-field', 'searchinput', 'search-input', 'searchquery', 'search-query',
|
||||
'filter', 'filterable', 'filterinput', 'filter-input', 'filterfield', 'filter-field', 'filterbox', 'filter-box'
|
||||
];
|
||||
|
||||
/**
|
||||
* English words to filter out from page titles during autofill matching to
|
||||
* prevent generic words from causing false positives.
|
||||
@@ -158,6 +175,14 @@ export const DutchFieldPatterns: FieldPatterns = {
|
||||
totp: ['verificatiecode', 'eenmalig', 'authenticatie', 'tweefactor', 'beveiligingscode']
|
||||
};
|
||||
|
||||
/**
|
||||
* Dutch field exclusion patterns. These patterns identify fields that should NOT trigger autofill.
|
||||
*/
|
||||
export const DutchFieldExclusionPatterns: FieldExclusionPatterns = [
|
||||
'zoeken', 'zoek', 'zoekveld', 'zoek-veld', 'zoekinput', 'zoek-input', 'zoekbox', 'zoek-box',
|
||||
'filter', 'filteren', 'filterveld', 'filter-veld', 'filterinput', 'filter-input'
|
||||
];
|
||||
|
||||
/**
|
||||
* Dutch gender option patterns
|
||||
*/
|
||||
@@ -314,3 +339,13 @@ export const CombinedEmailVerificationPatterns: EmailVerificationPatterns = {
|
||||
...DutchEmailVerificationPatterns.changeEmail
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Combined field exclusion patterns from all supported languages. These patterns identify fields
|
||||
* that should NOT trigger autofill, regardless of whether they match other field patterns.
|
||||
* This prevents false positives on search boxes and filters commonly found
|
||||
* in admin panels, data tables, and navigation areas.
|
||||
*/
|
||||
export const CombinedFieldExclusionPatterns: FieldExclusionPatterns = [
|
||||
...new Set([...EnglishFieldExclusionPatterns, ...DutchFieldExclusionPatterns])
|
||||
];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CombinedEmailVerificationPatterns, CombinedFieldPatterns, CombinedGenderOptionPatterns, CombinedStopWords } from "./FieldPatterns";
|
||||
import { CombinedEmailVerificationPatterns, CombinedFieldExclusionPatterns, CombinedFieldPatterns, CombinedGenderOptionPatterns, CombinedStopWords } from "./FieldPatterns";
|
||||
import { DetectedFieldType, FormFields } from "./types/FormFields";
|
||||
|
||||
/**
|
||||
@@ -210,6 +210,66 @@ export class FormDetector {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an input field matches exclusion patterns (search, filter, query fields).
|
||||
* These fields should not trigger autofill even if they match other patterns.
|
||||
* Uses whole-word matching to avoid false positives (e.g., "date" shouldn't match "birthdate").
|
||||
* @param input - The input element to check.
|
||||
* @returns True if the field matches exclusion patterns and should be excluded from autofill.
|
||||
*/
|
||||
private matchesExclusionPatterns(input: HTMLInputElement): boolean {
|
||||
// Collect all text attributes to check
|
||||
const attributesToCheck = [
|
||||
input.id,
|
||||
input.getAttribute('name'),
|
||||
input.getAttribute('placeholder'),
|
||||
input.getAttribute('class'),
|
||||
input.getAttribute('aria-label')
|
||||
]
|
||||
.map(a => a?.toLowerCase() ?? '')
|
||||
.filter(a => a.length > 0);
|
||||
|
||||
// Also check associated labels
|
||||
if (input.id || input.getAttribute('name')) {
|
||||
const label = this.document.querySelector(`label[for="${input.id || input.getAttribute('name')}"]`);
|
||||
if (label) {
|
||||
attributesToCheck.push(label.textContent?.toLowerCase() ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
// Use the combined exclusion patterns
|
||||
const allExclusionPatterns = CombinedFieldExclusionPatterns;
|
||||
|
||||
/*
|
||||
* Check if any attribute contains any exclusion pattern
|
||||
* Use whole-word or compound-word matching to avoid false positives
|
||||
*/
|
||||
for (const attr of attributesToCheck) {
|
||||
for (const pattern of allExclusionPatterns) {
|
||||
/*
|
||||
* Check for whole-word matches or compound word matches (search-box, searchInput, etc.)
|
||||
* Pattern must be:
|
||||
* - At the start: "search", "searchbox", "search-box", "search_box"
|
||||
* - In the middle: "user-search", "data_search"
|
||||
* - At the end: "quick-search"
|
||||
* But NOT within another word: "research" (re-search), "birthdate" (date)
|
||||
*
|
||||
* Word boundaries: start of string, space, hyphen, underscore, or transition from lowercase to uppercase
|
||||
*/
|
||||
const wordBoundaryPattern = new RegExp(
|
||||
`(^|[\\s\\-_]|(?<=[a-z])(?=[A-Z]))${pattern}($|[\\s\\-_]|(?<=[a-z])(?=[A-Z]))`,
|
||||
'i'
|
||||
);
|
||||
|
||||
if (wordBoundaryPattern.test(attr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an input field is likely a fake/honeypot field used to prevent autofill.
|
||||
* These fields are intentionally hidden from users but present in the DOM.
|
||||
@@ -543,6 +603,14 @@ export class FormDetector {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip fields that match exclusion patterns (search, filter, query fields).
|
||||
* These should never trigger autofill, even if they match other patterns.
|
||||
*/
|
||||
if (this.matchesExclusionPatterns(input as HTMLInputElement)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip fake/honeypot fields (e.g., fields with "fake" in name/id, tabindex="-1", etc.)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user