@metamask-previews/phishing-controller 12.0.2-preview-367cb1da → 12.0.2-preview-cf09c0a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PhishingController.cjs +453 -0
- package/dist/PhishingController.cjs.map +1 -0
- package/dist/{types/PhishingController.d.ts → PhishingController.d.cts} +4 -4
- package/dist/PhishingController.d.cts.map +1 -0
- package/dist/PhishingController.d.mts +304 -0
- package/dist/PhishingController.d.mts.map +1 -0
- package/dist/PhishingController.mjs +448 -37
- package/dist/PhishingController.mjs.map +1 -1
- package/dist/PhishingDetector.cjs +233 -0
- package/dist/PhishingDetector.cjs.map +1 -0
- package/dist/{types/PhishingDetector.d.ts → PhishingDetector.d.cts} +2 -2
- package/dist/PhishingDetector.d.cts.map +1 -0
- package/dist/PhishingDetector.d.mts +64 -0
- package/dist/PhishingDetector.d.mts.map +1 -0
- package/dist/PhishingDetector.mjs +227 -7
- package/dist/PhishingDetector.mjs.map +1 -1
- package/dist/index.cjs +23 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +3 -41
- package/dist/index.mjs.map +1 -1
- package/dist/tests/utils.cjs +24 -0
- package/dist/tests/utils.cjs.map +1 -0
- package/dist/{types/tests/utils.d.ts → tests/utils.d.cts} +1 -1
- package/dist/tests/utils.d.cts.map +1 -0
- package/dist/tests/utils.d.mts +11 -0
- package/dist/tests/utils.d.mts.map +1 -0
- package/dist/tests/utils.mjs +18 -14
- package/dist/tests/utils.mjs.map +1 -1
- package/dist/types.cjs +40 -0
- package/dist/types.cjs.map +1 -0
- package/dist/{types/types.d.ts → types.d.cts} +1 -1
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +50 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +36 -7
- package/dist/types.mjs.map +1 -1
- package/dist/utils.cjs +242 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/{types/utils.d.ts → utils.d.cts} +4 -4
- package/dist/utils.d.cts.map +1 -0
- package/dist/utils.d.mts +119 -0
- package/dist/utils.d.mts.map +1 -0
- package/dist/utils.mjs +224 -31
- package/dist/utils.mjs.map +1 -1
- package/package.json +12 -7
- package/dist/PhishingController.js +0 -39
- package/dist/PhishingController.js.map +0 -1
- package/dist/PhishingDetector.js +0 -9
- package/dist/PhishingDetector.js.map +0 -1
- package/dist/chunk-5NDIXQG5.js +0 -16
- package/dist/chunk-5NDIXQG5.js.map +0 -1
- package/dist/chunk-G2RL74NS.mjs +0 -16
- package/dist/chunk-G2RL74NS.mjs.map +0 -1
- package/dist/chunk-I3U4U3MW.mjs +0 -812
- package/dist/chunk-I3U4U3MW.mjs.map +0 -1
- package/dist/chunk-XUI43LEZ.mjs +0 -30
- package/dist/chunk-XUI43LEZ.mjs.map +0 -1
- package/dist/chunk-Z4BLTVTB.js +0 -30
- package/dist/chunk-Z4BLTVTB.js.map +0 -1
- package/dist/chunk-ZAOBCAQT.js +0 -812
- package/dist/chunk-ZAOBCAQT.js.map +0 -1
- package/dist/index.js +0 -42
- package/dist/index.js.map +0 -1
- package/dist/tests/utils.js +0 -16
- package/dist/tests/utils.js.map +0 -1
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/dist/types/PhishingController.d.ts.map +0 -1
- package/dist/types/PhishingDetector.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -5
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/tests/utils.d.ts.map +0 -1
- package/dist/types/types.d.ts.map +0 -1
- package/dist/types/utils.d.ts.map +0 -1
- package/dist/types.js +0 -8
- package/dist/types.js.map +0 -1
- package/dist/utils.js +0 -33
- package/dist/utils.js.map +0 -1
package/dist/chunk-ZAOBCAQT.js
DELETED
|
@@ -1,812 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var _chunkZ4BLTVTBjs = require('./chunk-Z4BLTVTB.js');
|
|
7
|
-
|
|
8
|
-
// src/utils.ts
|
|
9
|
-
var _utils = require('@noble/hashes/utils');
|
|
10
|
-
var _sha256 = require('ethereum-cryptography/sha256');
|
|
11
|
-
|
|
12
|
-
// src/PhishingController.ts
|
|
13
|
-
var _basecontroller = require('@metamask/base-controller');
|
|
14
|
-
var _controllerutils = require('@metamask/controller-utils');
|
|
15
|
-
var _ = require('punycode/');
|
|
16
|
-
|
|
17
|
-
// src/PhishingDetector.ts
|
|
18
|
-
var _fastestlevenshtein = require('fastest-levenshtein');
|
|
19
|
-
var _configs, _legacyConfig, _check, check_fn;
|
|
20
|
-
var PhishingDetector = class {
|
|
21
|
-
/**
|
|
22
|
-
* Construct a phishing detector, which can check whether origins are known
|
|
23
|
-
* to be malicious or similar to common phishing targets.
|
|
24
|
-
*
|
|
25
|
-
* A list of configurations is accepted. Each origin checked is processed
|
|
26
|
-
* using each configuration in sequence, so the order defines which
|
|
27
|
-
* configurations take precedence.
|
|
28
|
-
*
|
|
29
|
-
* @param opts - Phishing detection options
|
|
30
|
-
*/
|
|
31
|
-
constructor(opts) {
|
|
32
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _check);
|
|
33
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _configs, void 0);
|
|
34
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _legacyConfig, void 0);
|
|
35
|
-
if (Array.isArray(opts)) {
|
|
36
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _configs, processConfigs(opts));
|
|
37
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _legacyConfig, false);
|
|
38
|
-
} else {
|
|
39
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _configs, [
|
|
40
|
-
getDefaultPhishingDetectorConfig({
|
|
41
|
-
allowlist: opts.whitelist,
|
|
42
|
-
blocklist: opts.blacklist,
|
|
43
|
-
c2DomainBlocklist: opts.c2DomainBlocklist,
|
|
44
|
-
fuzzylist: opts.fuzzylist,
|
|
45
|
-
tolerance: opts.tolerance
|
|
46
|
-
})
|
|
47
|
-
]);
|
|
48
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _legacyConfig, true);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Check if a url is known to be malicious or similar to a common phishing
|
|
53
|
-
* target. This will check the hostname and IPFS CID that is sometimes
|
|
54
|
-
* located in the path.
|
|
55
|
-
*
|
|
56
|
-
* @param url - The url to check.
|
|
57
|
-
* @returns The result of the check.
|
|
58
|
-
*/
|
|
59
|
-
check(url) {
|
|
60
|
-
const result = _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _check, check_fn).call(this, url);
|
|
61
|
-
if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _legacyConfig)) {
|
|
62
|
-
let legacyType = result.type;
|
|
63
|
-
if (legacyType === "allowlist" /* Allowlist */) {
|
|
64
|
-
legacyType = "whitelist" /* Whitelist */;
|
|
65
|
-
} else if (legacyType === "blocklist" /* Blocklist */) {
|
|
66
|
-
legacyType = "blacklist" /* Blacklist */;
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
match: result.match,
|
|
70
|
-
result: result.result,
|
|
71
|
-
type: legacyType
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Checks if a URL is blocked against the hashed request blocklist.
|
|
78
|
-
* This is done by hashing the URL's hostname and checking it against the hashed request blocklist.
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* @param urlString - The URL to check.
|
|
82
|
-
* @returns An object indicating if the URL is blocked and relevant metadata.
|
|
83
|
-
*/
|
|
84
|
-
isMaliciousC2Domain(urlString) {
|
|
85
|
-
let hostname;
|
|
86
|
-
try {
|
|
87
|
-
hostname = new URL(urlString).hostname;
|
|
88
|
-
} catch (error) {
|
|
89
|
-
return {
|
|
90
|
-
result: false,
|
|
91
|
-
type: "c2DomainBlocklist" /* C2DomainBlocklist */
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
const fqdn = hostname.endsWith(".") ? hostname.slice(0, -1) : hostname;
|
|
95
|
-
const source = domainToParts(fqdn);
|
|
96
|
-
for (const { allowlist, name, version } of _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _configs)) {
|
|
97
|
-
const allowlistMatch = matchPartsAgainstList(source, allowlist);
|
|
98
|
-
if (allowlistMatch) {
|
|
99
|
-
const match = domainPartsToDomain(allowlistMatch);
|
|
100
|
-
return {
|
|
101
|
-
match,
|
|
102
|
-
name,
|
|
103
|
-
result: false,
|
|
104
|
-
type: "allowlist" /* Allowlist */,
|
|
105
|
-
version: version === void 0 ? version : String(version)
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
for (const { c2DomainBlocklist, name, version } of _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _configs)) {
|
|
110
|
-
const hash = sha256Hash(hostname.toLowerCase());
|
|
111
|
-
const blocked = c2DomainBlocklist?.includes(hash) ?? false;
|
|
112
|
-
if (blocked) {
|
|
113
|
-
return {
|
|
114
|
-
name,
|
|
115
|
-
result: true,
|
|
116
|
-
type: "c2DomainBlocklist" /* C2DomainBlocklist */,
|
|
117
|
-
version: version === void 0 ? version : String(version)
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
result: false,
|
|
123
|
-
type: "c2DomainBlocklist" /* C2DomainBlocklist */
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
_configs = new WeakMap();
|
|
128
|
-
_legacyConfig = new WeakMap();
|
|
129
|
-
_check = new WeakSet();
|
|
130
|
-
check_fn = function(url) {
|
|
131
|
-
const ipfsCidMatch = url.match(ipfsCidRegex());
|
|
132
|
-
if (ipfsCidMatch !== null) {
|
|
133
|
-
const cID = ipfsCidMatch[0];
|
|
134
|
-
for (const { blocklist, name, version } of _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _configs)) {
|
|
135
|
-
const blocklistMatch = blocklist.filter((entries) => entries.length === 1).find((entries) => {
|
|
136
|
-
return entries[0] === cID;
|
|
137
|
-
});
|
|
138
|
-
if (blocklistMatch) {
|
|
139
|
-
return {
|
|
140
|
-
name,
|
|
141
|
-
match: cID,
|
|
142
|
-
result: true,
|
|
143
|
-
type: "blocklist" /* Blocklist */,
|
|
144
|
-
version: version === void 0 ? version : String(version)
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
let domain;
|
|
150
|
-
try {
|
|
151
|
-
domain = new URL(url).hostname;
|
|
152
|
-
} catch (error) {
|
|
153
|
-
return {
|
|
154
|
-
result: false,
|
|
155
|
-
type: "all" /* All */
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
const fqdn = domain.endsWith(".") ? domain.slice(0, -1) : domain;
|
|
159
|
-
const source = domainToParts(fqdn);
|
|
160
|
-
for (const { allowlist, name, version } of _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _configs)) {
|
|
161
|
-
const allowlistMatch = matchPartsAgainstList(source, allowlist);
|
|
162
|
-
if (allowlistMatch) {
|
|
163
|
-
const match = domainPartsToDomain(allowlistMatch);
|
|
164
|
-
return {
|
|
165
|
-
match,
|
|
166
|
-
name,
|
|
167
|
-
result: false,
|
|
168
|
-
type: "allowlist" /* Allowlist */,
|
|
169
|
-
version: version === void 0 ? version : String(version)
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
for (const { blocklist, fuzzylist, name, tolerance, version } of _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _configs)) {
|
|
174
|
-
const blocklistMatch = matchPartsAgainstList(source, blocklist);
|
|
175
|
-
if (blocklistMatch) {
|
|
176
|
-
const match = domainPartsToDomain(blocklistMatch);
|
|
177
|
-
return {
|
|
178
|
-
match,
|
|
179
|
-
name,
|
|
180
|
-
result: true,
|
|
181
|
-
type: "blocklist" /* Blocklist */,
|
|
182
|
-
version: version === void 0 ? version : String(version)
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
if (tolerance > 0) {
|
|
186
|
-
let fuzzyForm = domainPartsToFuzzyForm(source);
|
|
187
|
-
fuzzyForm = fuzzyForm.replace(/^www\./u, "");
|
|
188
|
-
const levenshteinMatched = fuzzylist.find((targetParts) => {
|
|
189
|
-
const fuzzyTarget = domainPartsToFuzzyForm(targetParts);
|
|
190
|
-
const dist = _fastestlevenshtein.distance.call(void 0, fuzzyForm, fuzzyTarget);
|
|
191
|
-
return dist <= tolerance;
|
|
192
|
-
});
|
|
193
|
-
if (levenshteinMatched) {
|
|
194
|
-
const match = domainPartsToDomain(levenshteinMatched);
|
|
195
|
-
return {
|
|
196
|
-
name,
|
|
197
|
-
match,
|
|
198
|
-
result: true,
|
|
199
|
-
type: "fuzzy" /* Fuzzy */,
|
|
200
|
-
version: version === void 0 ? version : String(version)
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return { result: false, type: "all" /* All */ };
|
|
206
|
-
};
|
|
207
|
-
function ipfsCidRegex() {
|
|
208
|
-
const reg = "Qm[1-9A-HJ-NP-Za-km-z]{44,}|b[A-Za-z2-7]{58,}|B[A-Z2-7]{58,}|z[1-9A-HJ-NP-Za-km-z]{48,}|F[0-9A-F]{50,}";
|
|
209
|
-
return new RegExp(reg, "u");
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// src/PhishingController.ts
|
|
213
|
-
var PHISHING_CONFIG_BASE_URL = "https://phishing-detection.api.cx.metamask.io";
|
|
214
|
-
var METAMASK_STALELIST_FILE = "/v1/stalelist";
|
|
215
|
-
var METAMASK_HOTLIST_DIFF_FILE = "/v1/diffsSince";
|
|
216
|
-
var CLIENT_SIDE_DETECION_BASE_URL = "https://client-side-detection.api.cx.metamask.io";
|
|
217
|
-
var C2_DOMAIN_BLOCKLIST_ENDPOINT = "/v1/request-blocklist";
|
|
218
|
-
var C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL = 15 * 60;
|
|
219
|
-
var HOTLIST_REFRESH_INTERVAL = 5 * 60;
|
|
220
|
-
var STALELIST_REFRESH_INTERVAL = 30 * 24 * 60 * 60;
|
|
221
|
-
var METAMASK_STALELIST_URL = `${PHISHING_CONFIG_BASE_URL}${METAMASK_STALELIST_FILE}`;
|
|
222
|
-
var METAMASK_HOTLIST_DIFF_URL = `${PHISHING_CONFIG_BASE_URL}${METAMASK_HOTLIST_DIFF_FILE}`;
|
|
223
|
-
var C2_DOMAIN_BLOCKLIST_URL = `${CLIENT_SIDE_DETECION_BASE_URL}${C2_DOMAIN_BLOCKLIST_ENDPOINT}`;
|
|
224
|
-
var ListKeys = /* @__PURE__ */ ((ListKeys2) => {
|
|
225
|
-
ListKeys2["EthPhishingDetectConfig"] = "eth_phishing_detect_config";
|
|
226
|
-
return ListKeys2;
|
|
227
|
-
})(ListKeys || {});
|
|
228
|
-
var ListNames = /* @__PURE__ */ ((ListNames2) => {
|
|
229
|
-
ListNames2["MetaMask"] = "MetaMask";
|
|
230
|
-
return ListNames2;
|
|
231
|
-
})(ListNames || {});
|
|
232
|
-
var phishingListNameKeyMap = {
|
|
233
|
-
["MetaMask" /* MetaMask */]: "eth_phishing_detect_config" /* EthPhishingDetectConfig */
|
|
234
|
-
};
|
|
235
|
-
var phishingListKeyNameMap = {
|
|
236
|
-
["eth_phishing_detect_config" /* EthPhishingDetectConfig */]: "MetaMask" /* MetaMask */
|
|
237
|
-
};
|
|
238
|
-
var controllerName = "PhishingController";
|
|
239
|
-
var metadata = {
|
|
240
|
-
phishingLists: { persist: true, anonymous: false },
|
|
241
|
-
whitelist: { persist: true, anonymous: false },
|
|
242
|
-
hotlistLastFetched: { persist: true, anonymous: false },
|
|
243
|
-
stalelistLastFetched: { persist: true, anonymous: false },
|
|
244
|
-
c2DomainBlocklistLastFetched: { persist: true, anonymous: false }
|
|
245
|
-
};
|
|
246
|
-
var getDefaultState = () => {
|
|
247
|
-
return {
|
|
248
|
-
phishingLists: [],
|
|
249
|
-
whitelist: [],
|
|
250
|
-
hotlistLastFetched: 0,
|
|
251
|
-
stalelistLastFetched: 0,
|
|
252
|
-
c2DomainBlocklistLastFetched: 0
|
|
253
|
-
};
|
|
254
|
-
};
|
|
255
|
-
var _detector, _stalelistRefreshInterval, _hotlistRefreshInterval, _c2DomainBlocklistRefreshInterval, _inProgressHotlistUpdate, _inProgressStalelistUpdate, _isProgressC2DomainBlocklistUpdate, _registerMessageHandlers, registerMessageHandlers_fn, _updateStalelist, updateStalelist_fn, _updateHotlist, updateHotlist_fn, _updateC2DomainBlocklist, updateC2DomainBlocklist_fn, _queryConfig, queryConfig_fn;
|
|
256
|
-
var PhishingController = class extends _basecontroller.BaseController {
|
|
257
|
-
/**
|
|
258
|
-
* Construct a Phishing Controller.
|
|
259
|
-
*
|
|
260
|
-
* @param config - Initial options used to configure this controller.
|
|
261
|
-
* @param config.stalelistRefreshInterval - Polling interval used to fetch stale list.
|
|
262
|
-
* @param config.hotlistRefreshInterval - Polling interval used to fetch hotlist diff list.
|
|
263
|
-
* @param config.c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
|
|
264
|
-
* @param config.messenger - The controller restricted messenger.
|
|
265
|
-
* @param config.state - Initial state to set on this controller.
|
|
266
|
-
*/
|
|
267
|
-
constructor({
|
|
268
|
-
stalelistRefreshInterval = STALELIST_REFRESH_INTERVAL,
|
|
269
|
-
hotlistRefreshInterval = HOTLIST_REFRESH_INTERVAL,
|
|
270
|
-
c2DomainBlocklistRefreshInterval = C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL,
|
|
271
|
-
messenger,
|
|
272
|
-
state = {}
|
|
273
|
-
}) {
|
|
274
|
-
super({
|
|
275
|
-
name: controllerName,
|
|
276
|
-
metadata,
|
|
277
|
-
messenger,
|
|
278
|
-
state: {
|
|
279
|
-
...getDefaultState(),
|
|
280
|
-
...state
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
/**
|
|
284
|
-
* Constructor helper for registering this controller's messaging system
|
|
285
|
-
* actions.
|
|
286
|
-
*/
|
|
287
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _registerMessageHandlers);
|
|
288
|
-
/**
|
|
289
|
-
* Update the stalelist configuration.
|
|
290
|
-
*
|
|
291
|
-
* This should only be called from the `updateStalelist` function, which is a wrapper around
|
|
292
|
-
* this function that prevents redundant configuration updates.
|
|
293
|
-
*/
|
|
294
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _updateStalelist);
|
|
295
|
-
/**
|
|
296
|
-
* Update the stalelist configuration.
|
|
297
|
-
*
|
|
298
|
-
* This should only be called from the `updateStalelist` function, which is a wrapper around
|
|
299
|
-
* this function that prevents redundant configuration updates.
|
|
300
|
-
*/
|
|
301
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _updateHotlist);
|
|
302
|
-
/**
|
|
303
|
-
* Update the C2 domain blocklist.
|
|
304
|
-
*
|
|
305
|
-
* This should only be called from the `updateC2DomainBlocklist` function, which is a wrapper around
|
|
306
|
-
* this function that prevents redundant configuration updates.
|
|
307
|
-
*/
|
|
308
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _updateC2DomainBlocklist);
|
|
309
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _queryConfig);
|
|
310
|
-
// TODO: Replace `any` with type
|
|
311
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
312
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _detector, void 0);
|
|
313
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _stalelistRefreshInterval, void 0);
|
|
314
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _hotlistRefreshInterval, void 0);
|
|
315
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _c2DomainBlocklistRefreshInterval, void 0);
|
|
316
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _inProgressHotlistUpdate, void 0);
|
|
317
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _inProgressStalelistUpdate, void 0);
|
|
318
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _isProgressC2DomainBlocklistUpdate, void 0);
|
|
319
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _stalelistRefreshInterval, stalelistRefreshInterval);
|
|
320
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _hotlistRefreshInterval, hotlistRefreshInterval);
|
|
321
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _c2DomainBlocklistRefreshInterval, c2DomainBlocklistRefreshInterval);
|
|
322
|
-
_chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _registerMessageHandlers, registerMessageHandlers_fn).call(this);
|
|
323
|
-
this.updatePhishingDetector();
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Updates this.detector with an instance of PhishingDetector using the current state.
|
|
327
|
-
*/
|
|
328
|
-
updatePhishingDetector() {
|
|
329
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _detector, new PhishingDetector(this.state.phishingLists));
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Set the interval at which the stale phishing list will be refetched.
|
|
333
|
-
* Fetching will only occur on the next call to test/bypass.
|
|
334
|
-
* For immediate update to the phishing list, call {@link updateStalelist} directly.
|
|
335
|
-
*
|
|
336
|
-
* @param interval - the new interval, in ms.
|
|
337
|
-
*/
|
|
338
|
-
setStalelistRefreshInterval(interval) {
|
|
339
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _stalelistRefreshInterval, interval);
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Set the interval at which the hot list will be refetched.
|
|
343
|
-
* Fetching will only occur on the next call to test/bypass.
|
|
344
|
-
* For immediate update to the phishing list, call {@link updateHotlist} directly.
|
|
345
|
-
*
|
|
346
|
-
* @param interval - the new interval, in ms.
|
|
347
|
-
*/
|
|
348
|
-
setHotlistRefreshInterval(interval) {
|
|
349
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _hotlistRefreshInterval, interval);
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Set the interval at which the C2 domain blocklist will be refetched.
|
|
353
|
-
* Fetching will only occur on the next call to test/bypass.
|
|
354
|
-
* For immediate update to the phishing list, call {@link updateHotlist} directly.
|
|
355
|
-
*
|
|
356
|
-
* @param interval - the new interval, in ms.
|
|
357
|
-
*/
|
|
358
|
-
setC2DomainBlocklistRefreshInterval(interval) {
|
|
359
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _c2DomainBlocklistRefreshInterval, interval);
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Determine if an update to the stalelist configuration is needed.
|
|
363
|
-
*
|
|
364
|
-
* @returns Whether an update is needed
|
|
365
|
-
*/
|
|
366
|
-
isStalelistOutOfDate() {
|
|
367
|
-
return fetchTimeNow() - this.state.stalelistLastFetched >= _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _stalelistRefreshInterval);
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Determine if an update to the hotlist configuration is needed.
|
|
371
|
-
*
|
|
372
|
-
* @returns Whether an update is needed
|
|
373
|
-
*/
|
|
374
|
-
isHotlistOutOfDate() {
|
|
375
|
-
return fetchTimeNow() - this.state.hotlistLastFetched >= _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _hotlistRefreshInterval);
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Determine if an update to the C2 domain blocklist is needed.
|
|
379
|
-
*
|
|
380
|
-
* @returns Whether an update is needed
|
|
381
|
-
*/
|
|
382
|
-
isC2DomainBlocklistOutOfDate() {
|
|
383
|
-
return fetchTimeNow() - this.state.c2DomainBlocklistLastFetched >= _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _c2DomainBlocklistRefreshInterval);
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Conditionally update the phishing configuration.
|
|
387
|
-
*
|
|
388
|
-
* If the stalelist configuration is out of date, this function will call `updateStalelist`
|
|
389
|
-
* to update the configuration. This will automatically grab the hotlist,
|
|
390
|
-
* so it isn't necessary to continue on to download the hotlist and the c2 domain blocklist.
|
|
391
|
-
*
|
|
392
|
-
*/
|
|
393
|
-
async maybeUpdateState() {
|
|
394
|
-
const staleListOutOfDate = this.isStalelistOutOfDate();
|
|
395
|
-
if (staleListOutOfDate) {
|
|
396
|
-
await this.updateStalelist();
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
const hotlistOutOfDate = this.isHotlistOutOfDate();
|
|
400
|
-
if (hotlistOutOfDate) {
|
|
401
|
-
await this.updateHotlist();
|
|
402
|
-
}
|
|
403
|
-
const c2DomainBlocklistOutOfDate = this.isC2DomainBlocklistOutOfDate();
|
|
404
|
-
if (c2DomainBlocklistOutOfDate) {
|
|
405
|
-
await this.updateC2DomainBlocklist();
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
/**
|
|
409
|
-
* Determines if a given origin is unapproved.
|
|
410
|
-
*
|
|
411
|
-
* It is strongly recommended that you call {@link maybeUpdateState} before calling this,
|
|
412
|
-
* to check whether the phishing configuration is up-to-date. It will be updated if necessary
|
|
413
|
-
* by calling {@link updateStalelist} or {@link updateHotlist}.
|
|
414
|
-
*
|
|
415
|
-
* @param origin - Domain origin of a website.
|
|
416
|
-
* @returns Whether the origin is an unapproved origin.
|
|
417
|
-
*/
|
|
418
|
-
test(origin) {
|
|
419
|
-
const punycodeOrigin = _.toASCII.call(void 0, origin);
|
|
420
|
-
const hostname = getHostnameFromUrl(punycodeOrigin);
|
|
421
|
-
if (this.state.whitelist.includes(hostname || punycodeOrigin)) {
|
|
422
|
-
return { result: false, type: "all" /* All */ };
|
|
423
|
-
}
|
|
424
|
-
return _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _detector).check(punycodeOrigin);
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
* Checks if a request URL's domain is blocked against the request blocklist.
|
|
428
|
-
*
|
|
429
|
-
* This method is used to determine if a specific request URL is associated with a malicious
|
|
430
|
-
* command and control (C2) domain. The URL's hostname is hashed and checked against a configured
|
|
431
|
-
* blocklist of known malicious domains.
|
|
432
|
-
*
|
|
433
|
-
* @param origin - The full request URL to be checked.
|
|
434
|
-
* @returns An object indicating whether the URL's domain is blocked and relevant metadata.
|
|
435
|
-
*/
|
|
436
|
-
isBlockedRequest(origin) {
|
|
437
|
-
const punycodeOrigin = _.toASCII.call(void 0, origin);
|
|
438
|
-
const hostname = getHostnameFromUrl(punycodeOrigin);
|
|
439
|
-
if (this.state.whitelist.includes(hostname || punycodeOrigin)) {
|
|
440
|
-
return { result: false, type: "all" /* All */ };
|
|
441
|
-
}
|
|
442
|
-
return _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _detector).isMaliciousC2Domain(punycodeOrigin);
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Temporarily marks a given origin as approved.
|
|
446
|
-
*
|
|
447
|
-
* @param origin - The origin to mark as approved.
|
|
448
|
-
*/
|
|
449
|
-
bypass(origin) {
|
|
450
|
-
const punycodeOrigin = _.toASCII.call(void 0, origin);
|
|
451
|
-
const hostname = getHostnameFromUrl(punycodeOrigin);
|
|
452
|
-
const { whitelist } = this.state;
|
|
453
|
-
if (whitelist.includes(hostname || punycodeOrigin)) {
|
|
454
|
-
return;
|
|
455
|
-
}
|
|
456
|
-
this.update((draftState) => {
|
|
457
|
-
draftState.whitelist.push(hostname || punycodeOrigin);
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* Update the C2 domain blocklist.
|
|
462
|
-
*
|
|
463
|
-
* If an update is in progress, no additional update will be made. Instead this will wait until
|
|
464
|
-
* the in-progress update has finished.
|
|
465
|
-
*/
|
|
466
|
-
async updateC2DomainBlocklist() {
|
|
467
|
-
if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _isProgressC2DomainBlocklistUpdate)) {
|
|
468
|
-
await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _isProgressC2DomainBlocklistUpdate);
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
try {
|
|
472
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isProgressC2DomainBlocklistUpdate, _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _updateC2DomainBlocklist, updateC2DomainBlocklist_fn).call(this));
|
|
473
|
-
await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _isProgressC2DomainBlocklistUpdate);
|
|
474
|
-
} finally {
|
|
475
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isProgressC2DomainBlocklistUpdate, void 0);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* Update the hotlist.
|
|
480
|
-
*
|
|
481
|
-
* If an update is in progress, no additional update will be made. Instead this will wait until
|
|
482
|
-
* the in-progress update has finished.
|
|
483
|
-
*/
|
|
484
|
-
async updateHotlist() {
|
|
485
|
-
if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProgressHotlistUpdate)) {
|
|
486
|
-
await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProgressHotlistUpdate);
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
try {
|
|
490
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _inProgressHotlistUpdate, _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _updateHotlist, updateHotlist_fn).call(this));
|
|
491
|
-
await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProgressHotlistUpdate);
|
|
492
|
-
} finally {
|
|
493
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _inProgressHotlistUpdate, void 0);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* Update the stalelist.
|
|
498
|
-
*
|
|
499
|
-
* If an update is in progress, no additional update will be made. Instead this will wait until
|
|
500
|
-
* the in-progress update has finished.
|
|
501
|
-
*/
|
|
502
|
-
async updateStalelist() {
|
|
503
|
-
if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProgressStalelistUpdate)) {
|
|
504
|
-
await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProgressStalelistUpdate);
|
|
505
|
-
return;
|
|
506
|
-
}
|
|
507
|
-
try {
|
|
508
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _inProgressStalelistUpdate, _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _updateStalelist, updateStalelist_fn).call(this));
|
|
509
|
-
await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProgressStalelistUpdate);
|
|
510
|
-
} finally {
|
|
511
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _inProgressStalelistUpdate, void 0);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
};
|
|
515
|
-
_detector = new WeakMap();
|
|
516
|
-
_stalelistRefreshInterval = new WeakMap();
|
|
517
|
-
_hotlistRefreshInterval = new WeakMap();
|
|
518
|
-
_c2DomainBlocklistRefreshInterval = new WeakMap();
|
|
519
|
-
_inProgressHotlistUpdate = new WeakMap();
|
|
520
|
-
_inProgressStalelistUpdate = new WeakMap();
|
|
521
|
-
_isProgressC2DomainBlocklistUpdate = new WeakMap();
|
|
522
|
-
_registerMessageHandlers = new WeakSet();
|
|
523
|
-
registerMessageHandlers_fn = function() {
|
|
524
|
-
this.messagingSystem.registerActionHandler(
|
|
525
|
-
`${controllerName}:maybeUpdateState`,
|
|
526
|
-
this.maybeUpdateState.bind(this)
|
|
527
|
-
);
|
|
528
|
-
this.messagingSystem.registerActionHandler(
|
|
529
|
-
`${controllerName}:testOrigin`,
|
|
530
|
-
this.test.bind(this)
|
|
531
|
-
);
|
|
532
|
-
};
|
|
533
|
-
_updateStalelist = new WeakSet();
|
|
534
|
-
updateStalelist_fn = async function() {
|
|
535
|
-
let stalelistResponse = null;
|
|
536
|
-
let hotlistDiffsResponse = null;
|
|
537
|
-
let c2DomainBlocklistResponse = null;
|
|
538
|
-
try {
|
|
539
|
-
const stalelistPromise = _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _queryConfig, queryConfig_fn).call(this, METAMASK_STALELIST_URL);
|
|
540
|
-
const c2DomainBlocklistPromise = _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _queryConfig, queryConfig_fn).call(this, C2_DOMAIN_BLOCKLIST_URL);
|
|
541
|
-
[stalelistResponse, c2DomainBlocklistResponse] = await Promise.all([
|
|
542
|
-
stalelistPromise,
|
|
543
|
-
c2DomainBlocklistPromise
|
|
544
|
-
]);
|
|
545
|
-
if (stalelistResponse?.data && stalelistResponse.data.lastUpdated > 0) {
|
|
546
|
-
hotlistDiffsResponse = await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _queryConfig, queryConfig_fn).call(this, `${METAMASK_HOTLIST_DIFF_URL}/${stalelistResponse.data.lastUpdated}`);
|
|
547
|
-
}
|
|
548
|
-
} finally {
|
|
549
|
-
const timeNow = fetchTimeNow();
|
|
550
|
-
this.update((draftState) => {
|
|
551
|
-
draftState.stalelistLastFetched = timeNow;
|
|
552
|
-
draftState.hotlistLastFetched = timeNow;
|
|
553
|
-
draftState.c2DomainBlocklistLastFetched = timeNow;
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
if (!stalelistResponse || !hotlistDiffsResponse) {
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
559
|
-
const { eth_phishing_detect_config, ...partialState } = stalelistResponse.data;
|
|
560
|
-
const metamaskListState = {
|
|
561
|
-
...eth_phishing_detect_config,
|
|
562
|
-
...partialState,
|
|
563
|
-
c2DomainBlocklist: c2DomainBlocklistResponse ? c2DomainBlocklistResponse.recentlyAdded : [],
|
|
564
|
-
name: phishingListKeyNameMap.eth_phishing_detect_config
|
|
565
|
-
};
|
|
566
|
-
const newMetaMaskListState = applyDiffs(
|
|
567
|
-
metamaskListState,
|
|
568
|
-
hotlistDiffsResponse.data,
|
|
569
|
-
"eth_phishing_detect_config" /* EthPhishingDetectConfig */
|
|
570
|
-
);
|
|
571
|
-
this.update((draftState) => {
|
|
572
|
-
draftState.phishingLists = [newMetaMaskListState];
|
|
573
|
-
});
|
|
574
|
-
this.updatePhishingDetector();
|
|
575
|
-
};
|
|
576
|
-
_updateHotlist = new WeakSet();
|
|
577
|
-
updateHotlist_fn = async function() {
|
|
578
|
-
const lastDiffTimestamp = Math.max(
|
|
579
|
-
...this.state.phishingLists.map(({ lastUpdated }) => lastUpdated)
|
|
580
|
-
);
|
|
581
|
-
let hotlistResponse;
|
|
582
|
-
try {
|
|
583
|
-
hotlistResponse = await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _queryConfig, queryConfig_fn).call(this, `${METAMASK_HOTLIST_DIFF_URL}/${lastDiffTimestamp}`);
|
|
584
|
-
} finally {
|
|
585
|
-
this.update((draftState) => {
|
|
586
|
-
draftState.hotlistLastFetched = fetchTimeNow();
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
if (!hotlistResponse?.data) {
|
|
590
|
-
return;
|
|
591
|
-
}
|
|
592
|
-
const hotlist = hotlistResponse.data;
|
|
593
|
-
const newPhishingLists = this.state.phishingLists.map((phishingList) => {
|
|
594
|
-
const updatedList = applyDiffs(
|
|
595
|
-
phishingList,
|
|
596
|
-
hotlist,
|
|
597
|
-
phishingListNameKeyMap[phishingList.name],
|
|
598
|
-
[],
|
|
599
|
-
[]
|
|
600
|
-
);
|
|
601
|
-
return updatedList;
|
|
602
|
-
});
|
|
603
|
-
this.update((draftState) => {
|
|
604
|
-
draftState.phishingLists = newPhishingLists;
|
|
605
|
-
});
|
|
606
|
-
this.updatePhishingDetector();
|
|
607
|
-
};
|
|
608
|
-
_updateC2DomainBlocklist = new WeakSet();
|
|
609
|
-
updateC2DomainBlocklist_fn = async function() {
|
|
610
|
-
let c2DomainBlocklistResponse = null;
|
|
611
|
-
try {
|
|
612
|
-
c2DomainBlocklistResponse = await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _queryConfig, queryConfig_fn).call(this, `${C2_DOMAIN_BLOCKLIST_URL}?timestamp=${roundToNearestMinute(
|
|
613
|
-
this.state.c2DomainBlocklistLastFetched
|
|
614
|
-
)}`);
|
|
615
|
-
} finally {
|
|
616
|
-
this.update((draftState) => {
|
|
617
|
-
draftState.c2DomainBlocklistLastFetched = fetchTimeNow();
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
if (!c2DomainBlocklistResponse) {
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
const recentlyAddedC2Domains = c2DomainBlocklistResponse.recentlyAdded;
|
|
624
|
-
const recentlyRemovedC2Domains = c2DomainBlocklistResponse.recentlyRemoved;
|
|
625
|
-
const newPhishingLists = this.state.phishingLists.map((phishingList) => {
|
|
626
|
-
const updatedList = applyDiffs(
|
|
627
|
-
phishingList,
|
|
628
|
-
[],
|
|
629
|
-
phishingListNameKeyMap[phishingList.name],
|
|
630
|
-
recentlyAddedC2Domains,
|
|
631
|
-
recentlyRemovedC2Domains
|
|
632
|
-
);
|
|
633
|
-
return updatedList;
|
|
634
|
-
});
|
|
635
|
-
this.update((draftState) => {
|
|
636
|
-
draftState.phishingLists = newPhishingLists;
|
|
637
|
-
});
|
|
638
|
-
this.updatePhishingDetector();
|
|
639
|
-
};
|
|
640
|
-
_queryConfig = new WeakSet();
|
|
641
|
-
queryConfig_fn = async function(input) {
|
|
642
|
-
const response = await _controllerutils.safelyExecute.call(void 0,
|
|
643
|
-
() => fetch(input, { cache: "no-cache" }),
|
|
644
|
-
true
|
|
645
|
-
);
|
|
646
|
-
switch (response?.status) {
|
|
647
|
-
case 200: {
|
|
648
|
-
return await response.json();
|
|
649
|
-
}
|
|
650
|
-
default: {
|
|
651
|
-
return null;
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
};
|
|
655
|
-
var PhishingController_default = PhishingController;
|
|
656
|
-
|
|
657
|
-
// src/utils.ts
|
|
658
|
-
var DEFAULT_TOLERANCE = 3;
|
|
659
|
-
var fetchTimeNow = () => Math.round(Date.now() / 1e3);
|
|
660
|
-
function roundToNearestMinute(unixTimestamp) {
|
|
661
|
-
return Math.floor(unixTimestamp / 60) * 60;
|
|
662
|
-
}
|
|
663
|
-
var splitStringByPeriod = (stringToSplit) => {
|
|
664
|
-
const periodIndex = stringToSplit.indexOf(".");
|
|
665
|
-
return [
|
|
666
|
-
stringToSplit.slice(0, periodIndex),
|
|
667
|
-
stringToSplit.slice(periodIndex + 1)
|
|
668
|
-
];
|
|
669
|
-
};
|
|
670
|
-
var applyDiffs = (listState, hotlistDiffs, listKey, recentlyAddedC2Domains = [], recentlyRemovedC2Domains = []) => {
|
|
671
|
-
const diffsToApply = hotlistDiffs.filter(
|
|
672
|
-
({ timestamp, targetList }) => timestamp > listState.lastUpdated && splitStringByPeriod(targetList)[0] === listKey
|
|
673
|
-
);
|
|
674
|
-
let latestDiffTimestamp = listState.lastUpdated;
|
|
675
|
-
const listSets = {
|
|
676
|
-
allowlist: new Set(listState.allowlist),
|
|
677
|
-
blocklist: new Set(listState.blocklist),
|
|
678
|
-
fuzzylist: new Set(listState.fuzzylist),
|
|
679
|
-
c2DomainBlocklist: new Set(listState.c2DomainBlocklist)
|
|
680
|
-
};
|
|
681
|
-
for (const { isRemoval, targetList, url, timestamp } of diffsToApply) {
|
|
682
|
-
const targetListType = splitStringByPeriod(targetList)[1];
|
|
683
|
-
if (timestamp > latestDiffTimestamp) {
|
|
684
|
-
latestDiffTimestamp = timestamp;
|
|
685
|
-
}
|
|
686
|
-
if (isRemoval) {
|
|
687
|
-
listSets[targetListType].delete(url);
|
|
688
|
-
} else {
|
|
689
|
-
listSets[targetListType].add(url);
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
if (listKey === "eth_phishing_detect_config" /* EthPhishingDetectConfig */) {
|
|
693
|
-
for (const hash of recentlyAddedC2Domains) {
|
|
694
|
-
listSets.c2DomainBlocklist.add(hash);
|
|
695
|
-
}
|
|
696
|
-
for (const hash of recentlyRemovedC2Domains) {
|
|
697
|
-
listSets.c2DomainBlocklist.delete(hash);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
return {
|
|
701
|
-
c2DomainBlocklist: Array.from(listSets.c2DomainBlocklist),
|
|
702
|
-
allowlist: Array.from(listSets.allowlist),
|
|
703
|
-
blocklist: Array.from(listSets.blocklist),
|
|
704
|
-
fuzzylist: Array.from(listSets.fuzzylist),
|
|
705
|
-
version: listState.version,
|
|
706
|
-
name: phishingListKeyNameMap[listKey],
|
|
707
|
-
tolerance: listState.tolerance,
|
|
708
|
-
lastUpdated: latestDiffTimestamp
|
|
709
|
-
};
|
|
710
|
-
};
|
|
711
|
-
function validateConfig(config) {
|
|
712
|
-
if (config === null || typeof config !== "object") {
|
|
713
|
-
throw new Error("Invalid config");
|
|
714
|
-
}
|
|
715
|
-
if ("tolerance" in config && !("fuzzylist" in config)) {
|
|
716
|
-
throw new Error("Fuzzylist tolerance provided without fuzzylist");
|
|
717
|
-
}
|
|
718
|
-
if ("name" in config && (typeof config.name !== "string" || config.name === "")) {
|
|
719
|
-
throw new Error("Invalid config parameter: 'name'");
|
|
720
|
-
}
|
|
721
|
-
if ("version" in config && (!["number", "string"].includes(typeof config.version) || config.version === "")) {
|
|
722
|
-
throw new Error("Invalid config parameter: 'version'");
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
var domainToParts = (domain) => {
|
|
726
|
-
try {
|
|
727
|
-
return domain.split(".").reverse();
|
|
728
|
-
} catch (e) {
|
|
729
|
-
throw new Error(JSON.stringify(domain));
|
|
730
|
-
}
|
|
731
|
-
};
|
|
732
|
-
var processDomainList = (list) => {
|
|
733
|
-
return list.map(domainToParts);
|
|
734
|
-
};
|
|
735
|
-
var getDefaultPhishingDetectorConfig = ({
|
|
736
|
-
allowlist = [],
|
|
737
|
-
blocklist = [],
|
|
738
|
-
fuzzylist = [],
|
|
739
|
-
tolerance = DEFAULT_TOLERANCE
|
|
740
|
-
}) => ({
|
|
741
|
-
allowlist: processDomainList(allowlist),
|
|
742
|
-
blocklist: processDomainList(blocklist),
|
|
743
|
-
fuzzylist: processDomainList(fuzzylist),
|
|
744
|
-
tolerance
|
|
745
|
-
});
|
|
746
|
-
var processConfigs = (configs = []) => {
|
|
747
|
-
return configs.map((config) => {
|
|
748
|
-
validateConfig(config);
|
|
749
|
-
return { ...config, ...getDefaultPhishingDetectorConfig(config) };
|
|
750
|
-
});
|
|
751
|
-
};
|
|
752
|
-
var domainPartsToDomain = (domainParts) => {
|
|
753
|
-
return domainParts.slice().reverse().join(".");
|
|
754
|
-
};
|
|
755
|
-
var domainPartsToFuzzyForm = (domainParts) => {
|
|
756
|
-
return domainParts.slice(1).reverse().join(".");
|
|
757
|
-
};
|
|
758
|
-
var matchPartsAgainstList = (source, list) => {
|
|
759
|
-
return list.find((target) => {
|
|
760
|
-
if (target.length > source.length) {
|
|
761
|
-
return false;
|
|
762
|
-
}
|
|
763
|
-
return target.every((part, index) => source[index] === part);
|
|
764
|
-
});
|
|
765
|
-
};
|
|
766
|
-
var sha256Hash = (hostname) => {
|
|
767
|
-
const hashBuffer = _sha256.sha256.call(void 0, new TextEncoder().encode(hostname.toLowerCase()));
|
|
768
|
-
return _utils.bytesToHex.call(void 0, hashBuffer);
|
|
769
|
-
};
|
|
770
|
-
var getHostnameFromUrl = (url) => {
|
|
771
|
-
let hostname;
|
|
772
|
-
try {
|
|
773
|
-
hostname = new URL(url).hostname;
|
|
774
|
-
} catch (error) {
|
|
775
|
-
return null;
|
|
776
|
-
}
|
|
777
|
-
return hostname;
|
|
778
|
-
};
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
exports.fetchTimeNow = fetchTimeNow; exports.roundToNearestMinute = roundToNearestMinute; exports.applyDiffs = applyDiffs; exports.validateConfig = validateConfig; exports.domainToParts = domainToParts; exports.processDomainList = processDomainList; exports.getDefaultPhishingDetectorConfig = getDefaultPhishingDetectorConfig; exports.processConfigs = processConfigs; exports.domainPartsToDomain = domainPartsToDomain; exports.domainPartsToFuzzyForm = domainPartsToFuzzyForm; exports.matchPartsAgainstList = matchPartsAgainstList; exports.sha256Hash = sha256Hash; exports.getHostnameFromUrl = getHostnameFromUrl; exports.PhishingDetector = PhishingDetector; exports.PHISHING_CONFIG_BASE_URL = PHISHING_CONFIG_BASE_URL; exports.METAMASK_STALELIST_FILE = METAMASK_STALELIST_FILE; exports.METAMASK_HOTLIST_DIFF_FILE = METAMASK_HOTLIST_DIFF_FILE; exports.CLIENT_SIDE_DETECION_BASE_URL = CLIENT_SIDE_DETECION_BASE_URL; exports.C2_DOMAIN_BLOCKLIST_ENDPOINT = C2_DOMAIN_BLOCKLIST_ENDPOINT; exports.C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL = C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL; exports.HOTLIST_REFRESH_INTERVAL = HOTLIST_REFRESH_INTERVAL; exports.STALELIST_REFRESH_INTERVAL = STALELIST_REFRESH_INTERVAL; exports.METAMASK_STALELIST_URL = METAMASK_STALELIST_URL; exports.METAMASK_HOTLIST_DIFF_URL = METAMASK_HOTLIST_DIFF_URL; exports.C2_DOMAIN_BLOCKLIST_URL = C2_DOMAIN_BLOCKLIST_URL; exports.ListKeys = ListKeys; exports.ListNames = ListNames; exports.phishingListKeyNameMap = phishingListKeyNameMap; exports.PhishingController = PhishingController; exports.PhishingController_default = PhishingController_default;
|
|
812
|
-
//# sourceMappingURL=chunk-ZAOBCAQT.js.map
|