Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert PhishingDetector to Typescript #4138

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions packages/phishing-controller/src/PhishingDetector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { distance } from 'fastest-levenshtein';

import {
domainPartsToDomain,
domainPartsToFuzzyForm,
domainToParts,
getDefaultPhishingDetectorConfig,
matchPartsAgainstList,
processConfigs,
} from './utils';

export type PhishingDetectorConfiguration = {
name?: string;
version?: number | string;
allowlist: string[][];
blocklist: string[][];
fuzzylist: string[][];
tolerance: number;
};

export type LegacyPhishingDetectorConfiguration = {
whitelist: string[];
blacklist: string[];
fuzzylist: string[];
tolerance: number;
};

export type PhishingDetectorOptions =
| LegacyPhishingDetectorConfiguration
| PhishingDetectorConfiguration[];

export class PhishingDetector {
configs: PhishingDetectorConfiguration[];

legacyConfig: boolean;

/**
* Construct a phishing detector, which can check whether origins are known
* to be malicious or similar to common phishing targets.
*
* A list of configurations is accepted. Each origin checked is processed
* using each configuration in sequence, so the order defines which
* configurations take precedence.
*
* @param opts - Phishing detection options
*/
constructor(opts: PhishingDetectorOptions) {
// recommended configuration
if (Array.isArray(opts)) {
this.configs = processConfigs(opts);
this.legacyConfig = false;
// legacy configuration
} else {
this.configs = [
getDefaultPhishingDetectorConfig({
allowlist: opts.whitelist,
blocklist: opts.blacklist,
fuzzylist: opts.fuzzylist,
tolerance: opts.tolerance,
}),
];
this.legacyConfig = true;
}
}

check(domain: string) {
const result = this.#check(domain);

if (this.legacyConfig) {
let legacyType = result.type;
if (legacyType === 'allowlist') {
legacyType = 'whitelist';
} else if (legacyType === 'blocklist') {
legacyType = 'blacklist';
}
return {
match: result.match,
result: result.result,
type: legacyType,
};
}
return result;
}

#check(domain: string) {
const fqdn = domain.endsWith('.') ? domain.slice(0, -1) : domain;

const source = domainToParts(fqdn);

for (const { allowlist, name, version } of this.configs) {
// if source matches allowlist hostname (or subdomain thereof), PASS
const allowlistMatch = matchPartsAgainstList(source, allowlist);

Check failure on line 92 in packages/phishing-controller/src/PhishingDetector.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Build (20.x)

Argument of type 'string[][]' is not assignable to parameter of type 'string[]'.

Check failure on line 92 in packages/phishing-controller/src/PhishingDetector.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Build (20.x)

Argument of type 'string[][]' is not assignable to parameter of type 'string[]'.
if (allowlistMatch) {
const match = domainPartsToDomain(allowlistMatch);

Check failure on line 94 in packages/phishing-controller/src/PhishingDetector.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Build (20.x)

Argument of type 'string' is not assignable to parameter of type 'string[]'.

Check failure on line 94 in packages/phishing-controller/src/PhishingDetector.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Build (20.x)

Argument of type 'string' is not assignable to parameter of type 'string[]'.
return { match, name, result: false, type: 'allowlist', version };
}
}

for (const { blocklist, fuzzylist, name, tolerance, version } of this
.configs) {
// if source matches blocklist hostname (or subdomain thereof), FAIL
const blocklistMatch = matchPartsAgainstList(source, blocklist);

Check failure on line 102 in packages/phishing-controller/src/PhishingDetector.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Build (20.x)

Argument of type 'string[][]' is not assignable to parameter of type 'string[]'.

Check failure on line 102 in packages/phishing-controller/src/PhishingDetector.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Build (20.x)

Argument of type 'string[][]' is not assignable to parameter of type 'string[]'.
if (blocklistMatch) {
const match = domainPartsToDomain(blocklistMatch);

Check failure on line 104 in packages/phishing-controller/src/PhishingDetector.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Build (20.x)

Argument of type 'string' is not assignable to parameter of type 'string[]'.

Check failure on line 104 in packages/phishing-controller/src/PhishingDetector.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Build (20.x)

Argument of type 'string' is not assignable to parameter of type 'string[]'.
return { match, name, result: true, type: 'blocklist', version };
}

if (tolerance > 0) {
// check if near-match of whitelist domain, FAIL
let fuzzyForm = domainPartsToFuzzyForm(source);
// strip www
fuzzyForm = fuzzyForm.replace(/^www\./u, '');
// check against fuzzylist
const levenshteinMatched = fuzzylist.find((targetParts) => {
const fuzzyTarget = domainPartsToFuzzyForm(targetParts);
const dist = distance(fuzzyForm, fuzzyTarget);
return dist <= tolerance;
});
if (levenshteinMatched) {
const match = domainPartsToDomain(levenshteinMatched);
return { name, match, result: true, type: 'fuzzy', version };
}
}
}

// matched nothing, PASS
return { result: false, type: 'all' };
}
}
176 changes: 0 additions & 176 deletions packages/phishing-controller/src/detector.js

This file was deleted.

Loading
Loading