@metamask-previews/phishing-controller 11.0.0-preview-02e7ff99 → 12.0.0-preview-04657153
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/CHANGELOG.md +25 -1
- package/dist/PhishingController.js +11 -2
- package/dist/PhishingController.mjs +10 -1
- package/dist/PhishingDetector.js +3 -2
- package/dist/PhishingDetector.mjs +2 -1
- package/dist/chunk-5NDIXQG5.js +16 -0
- package/dist/chunk-5NDIXQG5.js.map +1 -0
- package/dist/{chunk-Q42CM6EP.mjs → chunk-F7CZ3O4X.mjs} +246 -43
- package/dist/chunk-F7CZ3O4X.mjs.map +1 -0
- package/dist/chunk-G2RL74NS.mjs +16 -0
- package/dist/chunk-G2RL74NS.mjs.map +1 -0
- package/dist/{chunk-DPHXQJ4E.js → chunk-XZNT2KYX.js} +247 -44
- package/dist/chunk-XZNT2KYX.js.map +1 -0
- package/dist/index.js +11 -2
- package/dist/index.mjs +10 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/PhishingController.d.ts +61 -21
- package/dist/types/PhishingController.d.ts.map +1 -1
- package/dist/types/PhishingDetector.d.ts +14 -37
- package/dist/types/PhishingDetector.d.ts.map +1 -1
- package/dist/types/types.d.ts +50 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils.d.ts +22 -2
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +8 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils.js +7 -2
- package/dist/utils.mjs +6 -1
- package/package.json +4 -2
- package/dist/chunk-DPHXQJ4E.js.map +0 -1
- package/dist/chunk-Q42CM6EP.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [12.0.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add allowlist functionality to the C2 domain detection system ([#4464](https://github.com/MetaMask/core/pull/4644))
|
|
15
|
+
- Add `PhishingController` functionality for blocking client-side C2 requests by managing a hashed C2 request blocklist ([#4526](https://github.com/MetaMask/core/pull/4526))
|
|
16
|
+
- Add `requestBlocklist` type to `ListTypes`.
|
|
17
|
+
- Add `isBlockedRequest` method to `PhishingController`.
|
|
18
|
+
- Add `isMaliciousRequestDomain` method to `PhishingDetector`.
|
|
19
|
+
- Add handling of `requestBlocklist` in `PhishingDetector` configuration.
|
|
20
|
+
- Add logic to update and check `requestBlocklist` when updating a stale list.
|
|
21
|
+
- Add `sha256Hash` function to generate SHA-256 hash of a domain.
|
|
22
|
+
- Define and export new types: `PhishingControllerGetStateAction`, `PhishingControllerStateChangeEvent`, `PhishingControllerEvents` ([#4633](https://github.com/MetaMask/core/pull/4633))
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **BREAKING:** Add `@noble/hashes` `^1.4.0` as dependency ([#4526](https://github.com/MetaMask/core/pull/4526))
|
|
27
|
+
- **BREAKING:**: Add `ethereum-cryptography` `^2.1.2` as dependency ([#4526](https://github.com/MetaMask/core/pull/4526))
|
|
28
|
+
- **BREAKING:** `PhishingControllerMessenger` must allow internal events defined in the `PhishingControllerEvents` type ([#4633](https://github.com/MetaMask/core/pull/4633))
|
|
29
|
+
- Widen `PhishingControllerActions` to include the `PhishingController:getState` action ([#4633](https://github.com/MetaMask/core/pull/4633))
|
|
30
|
+
- Bump `@metamask/base-controller` from `^6.0.2` to `^6.0.3` ([#4625](https://github.com/MetaMask/core/pull/4625))
|
|
31
|
+
- Bump `@metamask/controller-utils` from `^11.0.2` to `^11.1.0` ([#4639](https://github.com/MetaMask/core/pull/4639))
|
|
32
|
+
|
|
10
33
|
## [11.0.0]
|
|
11
34
|
|
|
12
35
|
### Changed
|
|
@@ -228,7 +251,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
228
251
|
|
|
229
252
|
All changes listed after this point were applied to this package following the monorepo conversion.
|
|
230
253
|
|
|
231
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@
|
|
254
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@12.0.0...HEAD
|
|
255
|
+
[12.0.0]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@11.0.0...@metamask/phishing-controller@12.0.0
|
|
232
256
|
[11.0.0]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@10.1.1...@metamask/phishing-controller@11.0.0
|
|
233
257
|
[10.1.1]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@10.1.0...@metamask/phishing-controller@10.1.1
|
|
234
258
|
[10.1.0]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@10.0.0...@metamask/phishing-controller@10.1.0
|
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
var _chunkXZNT2KYXjs = require('./chunk-XZNT2KYX.js');
|
|
19
|
+
require('./chunk-5NDIXQG5.js');
|
|
15
20
|
require('./chunk-Z4BLTVTB.js');
|
|
16
21
|
|
|
17
22
|
|
|
@@ -26,5 +31,9 @@ require('./chunk-Z4BLTVTB.js');
|
|
|
26
31
|
|
|
27
32
|
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
exports.C2_DOMAIN_BLOCKLIST_ENDPOINT = _chunkXZNT2KYXjs.C2_DOMAIN_BLOCKLIST_ENDPOINT; exports.C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL = _chunkXZNT2KYXjs.C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL; exports.C2_DOMAIN_BLOCKLIST_URL = _chunkXZNT2KYXjs.C2_DOMAIN_BLOCKLIST_URL; exports.CLIENT_SIDE_DETECION_BASE_URL = _chunkXZNT2KYXjs.CLIENT_SIDE_DETECION_BASE_URL; exports.HOTLIST_REFRESH_INTERVAL = _chunkXZNT2KYXjs.HOTLIST_REFRESH_INTERVAL; exports.ListKeys = _chunkXZNT2KYXjs.ListKeys; exports.ListNames = _chunkXZNT2KYXjs.ListNames; exports.METAMASK_HOTLIST_DIFF_FILE = _chunkXZNT2KYXjs.METAMASK_HOTLIST_DIFF_FILE; exports.METAMASK_HOTLIST_DIFF_URL = _chunkXZNT2KYXjs.METAMASK_HOTLIST_DIFF_URL; exports.METAMASK_STALELIST_FILE = _chunkXZNT2KYXjs.METAMASK_STALELIST_FILE; exports.METAMASK_STALELIST_URL = _chunkXZNT2KYXjs.METAMASK_STALELIST_URL; exports.PHISHING_CONFIG_BASE_URL = _chunkXZNT2KYXjs.PHISHING_CONFIG_BASE_URL; exports.PhishingController = _chunkXZNT2KYXjs.PhishingController; exports.STALELIST_REFRESH_INTERVAL = _chunkXZNT2KYXjs.STALELIST_REFRESH_INTERVAL; exports.default = _chunkXZNT2KYXjs.PhishingController_default; exports.phishingListKeyNameMap = _chunkXZNT2KYXjs.phishingListKeyNameMap;
|
|
30
39
|
//# sourceMappingURL=PhishingController.js.map
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
+
C2_DOMAIN_BLOCKLIST_ENDPOINT,
|
|
3
|
+
C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL,
|
|
4
|
+
C2_DOMAIN_BLOCKLIST_URL,
|
|
5
|
+
CLIENT_SIDE_DETECION_BASE_URL,
|
|
2
6
|
HOTLIST_REFRESH_INTERVAL,
|
|
3
7
|
ListKeys,
|
|
4
8
|
ListNames,
|
|
@@ -11,9 +15,14 @@ import {
|
|
|
11
15
|
PhishingController_default,
|
|
12
16
|
STALELIST_REFRESH_INTERVAL,
|
|
13
17
|
phishingListKeyNameMap
|
|
14
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-F7CZ3O4X.mjs";
|
|
19
|
+
import "./chunk-G2RL74NS.mjs";
|
|
15
20
|
import "./chunk-XUI43LEZ.mjs";
|
|
16
21
|
export {
|
|
22
|
+
C2_DOMAIN_BLOCKLIST_ENDPOINT,
|
|
23
|
+
C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL,
|
|
24
|
+
C2_DOMAIN_BLOCKLIST_URL,
|
|
25
|
+
CLIENT_SIDE_DETECION_BASE_URL,
|
|
17
26
|
HOTLIST_REFRESH_INTERVAL,
|
|
18
27
|
ListKeys,
|
|
19
28
|
ListNames,
|
package/dist/PhishingDetector.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkXZNT2KYXjs = require('./chunk-XZNT2KYX.js');
|
|
4
|
+
require('./chunk-5NDIXQG5.js');
|
|
4
5
|
require('./chunk-Z4BLTVTB.js');
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
exports.PhishingDetector =
|
|
8
|
+
exports.PhishingDetector = _chunkXZNT2KYXjs.PhishingDetector;
|
|
8
9
|
//# sourceMappingURL=PhishingDetector.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/types.ts
|
|
2
|
+
var PhishingDetectorResultType = /* @__PURE__ */ ((PhishingDetectorResultType2) => {
|
|
3
|
+
PhishingDetectorResultType2["All"] = "all";
|
|
4
|
+
PhishingDetectorResultType2["Fuzzy"] = "fuzzy";
|
|
5
|
+
PhishingDetectorResultType2["Blocklist"] = "blocklist";
|
|
6
|
+
PhishingDetectorResultType2["Allowlist"] = "allowlist";
|
|
7
|
+
PhishingDetectorResultType2["Blacklist"] = "blacklist";
|
|
8
|
+
PhishingDetectorResultType2["Whitelist"] = "whitelist";
|
|
9
|
+
PhishingDetectorResultType2["C2DomainBlocklist"] = "c2DomainBlocklist";
|
|
10
|
+
return PhishingDetectorResultType2;
|
|
11
|
+
})(PhishingDetectorResultType || {});
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
exports.PhishingDetectorResultType = PhishingDetectorResultType;
|
|
16
|
+
//# sourceMappingURL=chunk-5NDIXQG5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"names":["PhishingDetectorResultType"],"mappings":";AAyCO,IAAK,6BAAL,kBAAKA,gCAAL;AAIL,EAAAA,4BAAA,SAAM;AAIN,EAAAA,4BAAA,WAAQ;AAIR,EAAAA,4BAAA,eAAY;AAIZ,EAAAA,4BAAA,eAAY;AAKZ,EAAAA,4BAAA,eAAY;AAKZ,EAAAA,4BAAA,eAAY;AAIZ,EAAAA,4BAAA,uBAAoB;AA9BV,SAAAA;AAAA,GAAA","sourcesContent":["/**\n * Represents the result of checking a domain.\n */\nexport type PhishingDetectorResult = {\n /**\n * The name of the configuration object in which the domain was found within\n * an allowlist, blocklist, or fuzzylist.\n */\n name?: string;\n /**\n * The version associated with the configuration object in which the domain\n * was found within an allowlist, blocklist, or fuzzylist.\n */\n version?: string;\n /**\n * Whether the domain is regarded as allowed (true) or not (false).\n */\n result: boolean;\n /**\n * A normalized version of the domain, which is only constructed if the domain\n * is found within a list.\n */\n match?: string;\n /**\n * Which type of list in which the domain was found.\n *\n * - \"allowlist\" means that the domain was found in the allowlist.\n * - \"blocklist\" means that the domain was found in the blocklist.\n * - \"fuzzy\" means that the domain was found in the fuzzylist.\n * - \"blacklist\" means that the domain was found in a blacklist of a legacy\n * configuration object.\n * - \"whitelist\" means that the domain was found in a whitelist of a legacy\n * configuration object.\n * - \"all\" means that the domain was not found in any list.\n */\n type: PhishingDetectorResultType;\n};\n\n/**\n * The type of list in which the domain was found.\n */\nexport enum PhishingDetectorResultType {\n /*\n * \"all\" means that the domain was not found in any list.\n */\n All = 'all',\n /*\n * \"fuzzy\" means that the domain was found in the fuzzylist.\n */\n Fuzzy = 'fuzzy',\n /*\n * \"blocklist\" means that the domain was found in the blocklist.\n */\n Blocklist = 'blocklist',\n /*\n * \"allowlist\" means that the domain was found in the allowlist.\n */\n Allowlist = 'allowlist',\n /*\n * \"blacklist\" means that the domain was found in a blacklist of a legacy\n * configuration object.\n */\n Blacklist = 'blacklist',\n /*\n * \"whitelist\" means that the domain was found in a whitelist of a legacy\n * configuration object.\n */\n Whitelist = 'whitelist',\n /*\n * \"c2DomainBlocklist\" means that the domain was found in the C2 domain blocklist.\n */\n C2DomainBlocklist = 'c2DomainBlocklist',\n}\n"]}
|
|
@@ -5,6 +5,10 @@ import {
|
|
|
5
5
|
__privateSet
|
|
6
6
|
} from "./chunk-XUI43LEZ.mjs";
|
|
7
7
|
|
|
8
|
+
// src/utils.ts
|
|
9
|
+
import { bytesToHex } from "@noble/hashes/utils";
|
|
10
|
+
import { sha256 } from "ethereum-cryptography/sha256";
|
|
11
|
+
|
|
8
12
|
// src/PhishingController.ts
|
|
9
13
|
import { BaseController } from "@metamask/base-controller";
|
|
10
14
|
import { safelyExecute } from "@metamask/controller-utils";
|
|
@@ -36,6 +40,7 @@ var PhishingDetector = class {
|
|
|
36
40
|
getDefaultPhishingDetectorConfig({
|
|
37
41
|
allowlist: opts.whitelist,
|
|
38
42
|
blocklist: opts.blacklist,
|
|
43
|
+
c2DomainBlocklist: opts.c2DomainBlocklist,
|
|
39
44
|
fuzzylist: opts.fuzzylist,
|
|
40
45
|
tolerance: opts.tolerance
|
|
41
46
|
})
|
|
@@ -55,10 +60,10 @@ var PhishingDetector = class {
|
|
|
55
60
|
const result = __privateMethod(this, _check, check_fn).call(this, url);
|
|
56
61
|
if (__privateGet(this, _legacyConfig)) {
|
|
57
62
|
let legacyType = result.type;
|
|
58
|
-
if (legacyType === "allowlist") {
|
|
59
|
-
legacyType = "whitelist"
|
|
60
|
-
} else if (legacyType === "blocklist") {
|
|
61
|
-
legacyType = "blacklist"
|
|
63
|
+
if (legacyType === "allowlist" /* Allowlist */) {
|
|
64
|
+
legacyType = "whitelist" /* Whitelist */;
|
|
65
|
+
} else if (legacyType === "blocklist" /* Blocklist */) {
|
|
66
|
+
legacyType = "blacklist" /* Blacklist */;
|
|
62
67
|
}
|
|
63
68
|
return {
|
|
64
69
|
match: result.match,
|
|
@@ -68,12 +73,88 @@ var PhishingDetector = class {
|
|
|
68
73
|
}
|
|
69
74
|
return result;
|
|
70
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 __privateGet(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 __privateGet(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
|
+
}
|
|
71
126
|
};
|
|
72
127
|
_configs = new WeakMap();
|
|
73
128
|
_legacyConfig = new WeakMap();
|
|
74
129
|
_check = new WeakSet();
|
|
75
130
|
check_fn = function(url) {
|
|
76
|
-
const
|
|
131
|
+
const ipfsCidMatch = url.match(ipfsCidRegex());
|
|
132
|
+
if (ipfsCidMatch !== null) {
|
|
133
|
+
const cID = ipfsCidMatch[0];
|
|
134
|
+
for (const { blocklist, name, version } of __privateGet(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
|
+
}
|
|
77
158
|
const fqdn = domain.endsWith(".") ? domain.slice(0, -1) : domain;
|
|
78
159
|
const source = domainToParts(fqdn);
|
|
79
160
|
for (const { allowlist, name, version } of __privateGet(this, _configs)) {
|
|
@@ -84,7 +165,7 @@ check_fn = function(url) {
|
|
|
84
165
|
match,
|
|
85
166
|
name,
|
|
86
167
|
result: false,
|
|
87
|
-
type: "allowlist"
|
|
168
|
+
type: "allowlist" /* Allowlist */,
|
|
88
169
|
version: version === void 0 ? version : String(version)
|
|
89
170
|
};
|
|
90
171
|
}
|
|
@@ -97,7 +178,7 @@ check_fn = function(url) {
|
|
|
97
178
|
match,
|
|
98
179
|
name,
|
|
99
180
|
result: true,
|
|
100
|
-
type: "blocklist"
|
|
181
|
+
type: "blocklist" /* Blocklist */,
|
|
101
182
|
version: version === void 0 ? version : String(version)
|
|
102
183
|
};
|
|
103
184
|
}
|
|
@@ -115,31 +196,13 @@ check_fn = function(url) {
|
|
|
115
196
|
name,
|
|
116
197
|
match,
|
|
117
198
|
result: true,
|
|
118
|
-
type: "fuzzy"
|
|
199
|
+
type: "fuzzy" /* Fuzzy */,
|
|
119
200
|
version: version === void 0 ? version : String(version)
|
|
120
201
|
};
|
|
121
202
|
}
|
|
122
203
|
}
|
|
123
204
|
}
|
|
124
|
-
|
|
125
|
-
if (ipfsCidMatch !== null) {
|
|
126
|
-
const cID = ipfsCidMatch[0];
|
|
127
|
-
for (const { blocklist, name, version } of __privateGet(this, _configs)) {
|
|
128
|
-
const blocklistMatch = blocklist.filter((entries) => entries.length === 1).find((entries) => {
|
|
129
|
-
return entries[0] === cID;
|
|
130
|
-
});
|
|
131
|
-
if (blocklistMatch) {
|
|
132
|
-
return {
|
|
133
|
-
name,
|
|
134
|
-
match: cID,
|
|
135
|
-
result: true,
|
|
136
|
-
type: "blocklist",
|
|
137
|
-
version: version === void 0 ? version : String(version)
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return { result: false, type: "all" };
|
|
205
|
+
return { result: false, type: "all" /* All */ };
|
|
143
206
|
};
|
|
144
207
|
function ipfsCidRegex() {
|
|
145
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,}";
|
|
@@ -150,10 +213,14 @@ function ipfsCidRegex() {
|
|
|
150
213
|
var PHISHING_CONFIG_BASE_URL = "https://phishing-detection.api.cx.metamask.io";
|
|
151
214
|
var METAMASK_STALELIST_FILE = "/v1/stalelist";
|
|
152
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;
|
|
153
219
|
var HOTLIST_REFRESH_INTERVAL = 5 * 60;
|
|
154
220
|
var STALELIST_REFRESH_INTERVAL = 30 * 24 * 60 * 60;
|
|
155
221
|
var METAMASK_STALELIST_URL = `${PHISHING_CONFIG_BASE_URL}${METAMASK_STALELIST_FILE}`;
|
|
156
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}`;
|
|
157
224
|
var ListKeys = /* @__PURE__ */ ((ListKeys2) => {
|
|
158
225
|
ListKeys2["EthPhishingDetectConfig"] = "eth_phishing_detect_config";
|
|
159
226
|
return ListKeys2;
|
|
@@ -173,17 +240,19 @@ var metadata = {
|
|
|
173
240
|
phishingLists: { persist: true, anonymous: false },
|
|
174
241
|
whitelist: { persist: true, anonymous: false },
|
|
175
242
|
hotlistLastFetched: { persist: true, anonymous: false },
|
|
176
|
-
stalelistLastFetched: { persist: true, anonymous: false }
|
|
243
|
+
stalelistLastFetched: { persist: true, anonymous: false },
|
|
244
|
+
c2DomainBlocklistLastFetched: { persist: true, anonymous: false }
|
|
177
245
|
};
|
|
178
246
|
var getDefaultState = () => {
|
|
179
247
|
return {
|
|
180
248
|
phishingLists: [],
|
|
181
249
|
whitelist: [],
|
|
182
250
|
hotlistLastFetched: 0,
|
|
183
|
-
stalelistLastFetched: 0
|
|
251
|
+
stalelistLastFetched: 0,
|
|
252
|
+
c2DomainBlocklistLastFetched: 0
|
|
184
253
|
};
|
|
185
254
|
};
|
|
186
|
-
var _detector, _stalelistRefreshInterval, _hotlistRefreshInterval, _inProgressHotlistUpdate, _inProgressStalelistUpdate, _registerMessageHandlers, registerMessageHandlers_fn, _updateStalelist, updateStalelist_fn, _updateHotlist, updateHotlist_fn, _queryConfig, queryConfig_fn;
|
|
255
|
+
var _detector, _stalelistRefreshInterval, _hotlistRefreshInterval, _c2DomainBlocklistRefreshInterval, _inProgressHotlistUpdate, _inProgressStalelistUpdate, _isProgressC2DomainBlocklistUpdate, _registerMessageHandlers, registerMessageHandlers_fn, _updateStalelist, updateStalelist_fn, _updateHotlist, updateHotlist_fn, _updateC2DomainBlocklist, updateC2DomainBlocklist_fn, _queryConfig, queryConfig_fn;
|
|
187
256
|
var PhishingController = class extends BaseController {
|
|
188
257
|
/**
|
|
189
258
|
* Construct a Phishing Controller.
|
|
@@ -191,12 +260,14 @@ var PhishingController = class extends BaseController {
|
|
|
191
260
|
* @param config - Initial options used to configure this controller.
|
|
192
261
|
* @param config.stalelistRefreshInterval - Polling interval used to fetch stale list.
|
|
193
262
|
* @param config.hotlistRefreshInterval - Polling interval used to fetch hotlist diff list.
|
|
263
|
+
* @param config.c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
|
|
194
264
|
* @param config.messenger - The controller restricted messenger.
|
|
195
265
|
* @param config.state - Initial state to set on this controller.
|
|
196
266
|
*/
|
|
197
267
|
constructor({
|
|
198
268
|
stalelistRefreshInterval = STALELIST_REFRESH_INTERVAL,
|
|
199
269
|
hotlistRefreshInterval = HOTLIST_REFRESH_INTERVAL,
|
|
270
|
+
c2DomainBlocklistRefreshInterval = C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL,
|
|
200
271
|
messenger,
|
|
201
272
|
state = {}
|
|
202
273
|
}) {
|
|
@@ -228,16 +299,26 @@ var PhishingController = class extends BaseController {
|
|
|
228
299
|
* this function that prevents redundant configuration updates.
|
|
229
300
|
*/
|
|
230
301
|
__privateAdd(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
|
+
__privateAdd(this, _updateC2DomainBlocklist);
|
|
231
309
|
__privateAdd(this, _queryConfig);
|
|
232
310
|
// TODO: Replace `any` with type
|
|
233
311
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
234
312
|
__privateAdd(this, _detector, void 0);
|
|
235
313
|
__privateAdd(this, _stalelistRefreshInterval, void 0);
|
|
236
314
|
__privateAdd(this, _hotlistRefreshInterval, void 0);
|
|
315
|
+
__privateAdd(this, _c2DomainBlocklistRefreshInterval, void 0);
|
|
237
316
|
__privateAdd(this, _inProgressHotlistUpdate, void 0);
|
|
238
317
|
__privateAdd(this, _inProgressStalelistUpdate, void 0);
|
|
318
|
+
__privateAdd(this, _isProgressC2DomainBlocklistUpdate, void 0);
|
|
239
319
|
__privateSet(this, _stalelistRefreshInterval, stalelistRefreshInterval);
|
|
240
320
|
__privateSet(this, _hotlistRefreshInterval, hotlistRefreshInterval);
|
|
321
|
+
__privateSet(this, _c2DomainBlocklistRefreshInterval, c2DomainBlocklistRefreshInterval);
|
|
241
322
|
__privateMethod(this, _registerMessageHandlers, registerMessageHandlers_fn).call(this);
|
|
242
323
|
this.updatePhishingDetector();
|
|
243
324
|
}
|
|
@@ -267,6 +348,16 @@ var PhishingController = class extends BaseController {
|
|
|
267
348
|
setHotlistRefreshInterval(interval) {
|
|
268
349
|
__privateSet(this, _hotlistRefreshInterval, interval);
|
|
269
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
|
+
__privateSet(this, _c2DomainBlocklistRefreshInterval, interval);
|
|
360
|
+
}
|
|
270
361
|
/**
|
|
271
362
|
* Determine if an update to the stalelist configuration is needed.
|
|
272
363
|
*
|
|
@@ -283,12 +374,20 @@ var PhishingController = class extends BaseController {
|
|
|
283
374
|
isHotlistOutOfDate() {
|
|
284
375
|
return fetchTimeNow() - this.state.hotlistLastFetched >= __privateGet(this, _hotlistRefreshInterval);
|
|
285
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 >= __privateGet(this, _c2DomainBlocklistRefreshInterval);
|
|
384
|
+
}
|
|
286
385
|
/**
|
|
287
386
|
* Conditionally update the phishing configuration.
|
|
288
387
|
*
|
|
289
388
|
* If the stalelist configuration is out of date, this function will call `updateStalelist`
|
|
290
389
|
* to update the configuration. This will automatically grab the hotlist,
|
|
291
|
-
* so it isn't necessary to continue on to download the hotlist.
|
|
390
|
+
* so it isn't necessary to continue on to download the hotlist and the c2 domain blocklist.
|
|
292
391
|
*
|
|
293
392
|
*/
|
|
294
393
|
async maybeUpdateState() {
|
|
@@ -301,6 +400,10 @@ var PhishingController = class extends BaseController {
|
|
|
301
400
|
if (hotlistOutOfDate) {
|
|
302
401
|
await this.updateHotlist();
|
|
303
402
|
}
|
|
403
|
+
const c2DomainBlocklistOutOfDate = this.isC2DomainBlocklistOutOfDate();
|
|
404
|
+
if (c2DomainBlocklistOutOfDate) {
|
|
405
|
+
await this.updateC2DomainBlocklist();
|
|
406
|
+
}
|
|
304
407
|
}
|
|
305
408
|
/**
|
|
306
409
|
* Determines if a given origin is unapproved.
|
|
@@ -315,10 +418,24 @@ var PhishingController = class extends BaseController {
|
|
|
315
418
|
test(origin) {
|
|
316
419
|
const punycodeOrigin = toASCII(origin);
|
|
317
420
|
if (this.state.whitelist.includes(punycodeOrigin)) {
|
|
318
|
-
return { result: false, type: "all" };
|
|
421
|
+
return { result: false, type: "all" /* All */ };
|
|
319
422
|
}
|
|
320
423
|
return __privateGet(this, _detector).check(punycodeOrigin);
|
|
321
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* Checks if a request URL's domain is blocked against the request blocklist.
|
|
427
|
+
*
|
|
428
|
+
* This method is used to determine if a specific request URL is associated with a malicious
|
|
429
|
+
* command and control (C2) domain. The URL's hostname is hashed and checked against a configured
|
|
430
|
+
* blocklist of known malicious domains.
|
|
431
|
+
*
|
|
432
|
+
* @param origin - The full request URL to be checked.
|
|
433
|
+
* @returns An object indicating whether the URL's domain is blocked and relevant metadata.
|
|
434
|
+
*/
|
|
435
|
+
isBlockedRequest(origin) {
|
|
436
|
+
const punycodeOrigin = toASCII(origin);
|
|
437
|
+
return __privateGet(this, _detector).isMaliciousC2Domain(punycodeOrigin);
|
|
438
|
+
}
|
|
322
439
|
/**
|
|
323
440
|
* Temporarily marks a given origin as approved.
|
|
324
441
|
*
|
|
@@ -334,6 +451,24 @@ var PhishingController = class extends BaseController {
|
|
|
334
451
|
draftState.whitelist.push(punycodeOrigin);
|
|
335
452
|
});
|
|
336
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Update the C2 domain blocklist.
|
|
456
|
+
*
|
|
457
|
+
* If an update is in progress, no additional update will be made. Instead this will wait until
|
|
458
|
+
* the in-progress update has finished.
|
|
459
|
+
*/
|
|
460
|
+
async updateC2DomainBlocklist() {
|
|
461
|
+
if (__privateGet(this, _isProgressC2DomainBlocklistUpdate)) {
|
|
462
|
+
await __privateGet(this, _isProgressC2DomainBlocklistUpdate);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
try {
|
|
466
|
+
__privateSet(this, _isProgressC2DomainBlocklistUpdate, __privateMethod(this, _updateC2DomainBlocklist, updateC2DomainBlocklist_fn).call(this));
|
|
467
|
+
await __privateGet(this, _isProgressC2DomainBlocklistUpdate);
|
|
468
|
+
} finally {
|
|
469
|
+
__privateSet(this, _isProgressC2DomainBlocklistUpdate, void 0);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
337
472
|
/**
|
|
338
473
|
* Update the hotlist.
|
|
339
474
|
*
|
|
@@ -374,8 +509,10 @@ var PhishingController = class extends BaseController {
|
|
|
374
509
|
_detector = new WeakMap();
|
|
375
510
|
_stalelistRefreshInterval = new WeakMap();
|
|
376
511
|
_hotlistRefreshInterval = new WeakMap();
|
|
512
|
+
_c2DomainBlocklistRefreshInterval = new WeakMap();
|
|
377
513
|
_inProgressHotlistUpdate = new WeakMap();
|
|
378
514
|
_inProgressStalelistUpdate = new WeakMap();
|
|
515
|
+
_isProgressC2DomainBlocklistUpdate = new WeakMap();
|
|
379
516
|
_registerMessageHandlers = new WeakSet();
|
|
380
517
|
registerMessageHandlers_fn = function() {
|
|
381
518
|
this.messagingSystem.registerActionHandler(
|
|
@@ -389,10 +526,16 @@ registerMessageHandlers_fn = function() {
|
|
|
389
526
|
};
|
|
390
527
|
_updateStalelist = new WeakSet();
|
|
391
528
|
updateStalelist_fn = async function() {
|
|
392
|
-
let stalelistResponse;
|
|
393
|
-
let hotlistDiffsResponse;
|
|
529
|
+
let stalelistResponse = null;
|
|
530
|
+
let hotlistDiffsResponse = null;
|
|
531
|
+
let c2DomainBlocklistResponse = null;
|
|
394
532
|
try {
|
|
395
|
-
|
|
533
|
+
const stalelistPromise = __privateMethod(this, _queryConfig, queryConfig_fn).call(this, METAMASK_STALELIST_URL);
|
|
534
|
+
const c2DomainBlocklistPromise = __privateMethod(this, _queryConfig, queryConfig_fn).call(this, C2_DOMAIN_BLOCKLIST_URL);
|
|
535
|
+
[stalelistResponse, c2DomainBlocklistResponse] = await Promise.all([
|
|
536
|
+
stalelistPromise,
|
|
537
|
+
c2DomainBlocklistPromise
|
|
538
|
+
]);
|
|
396
539
|
if (stalelistResponse?.data && stalelistResponse.data.lastUpdated > 0) {
|
|
397
540
|
hotlistDiffsResponse = await __privateMethod(this, _queryConfig, queryConfig_fn).call(this, `${METAMASK_HOTLIST_DIFF_URL}/${stalelistResponse.data.lastUpdated}`);
|
|
398
541
|
}
|
|
@@ -401,6 +544,7 @@ updateStalelist_fn = async function() {
|
|
|
401
544
|
this.update((draftState) => {
|
|
402
545
|
draftState.stalelistLastFetched = timeNow;
|
|
403
546
|
draftState.hotlistLastFetched = timeNow;
|
|
547
|
+
draftState.c2DomainBlocklistLastFetched = timeNow;
|
|
404
548
|
});
|
|
405
549
|
}
|
|
406
550
|
if (!stalelistResponse || !hotlistDiffsResponse) {
|
|
@@ -410,6 +554,7 @@ updateStalelist_fn = async function() {
|
|
|
410
554
|
const metamaskListState = {
|
|
411
555
|
...eth_phishing_detect_config,
|
|
412
556
|
...partialState,
|
|
557
|
+
c2DomainBlocklist: c2DomainBlocklistResponse ? c2DomainBlocklistResponse.recentlyAdded : [],
|
|
413
558
|
name: phishingListKeyNameMap.eth_phishing_detect_config
|
|
414
559
|
};
|
|
415
560
|
const newMetaMaskListState = applyDiffs(
|
|
@@ -439,13 +584,48 @@ updateHotlist_fn = async function() {
|
|
|
439
584
|
return;
|
|
440
585
|
}
|
|
441
586
|
const hotlist = hotlistResponse.data;
|
|
442
|
-
const newPhishingLists = this.state.phishingLists.map(
|
|
443
|
-
|
|
587
|
+
const newPhishingLists = this.state.phishingLists.map((phishingList) => {
|
|
588
|
+
const updatedList = applyDiffs(
|
|
444
589
|
phishingList,
|
|
445
590
|
hotlist,
|
|
446
|
-
phishingListNameKeyMap[phishingList.name]
|
|
447
|
-
|
|
448
|
-
|
|
591
|
+
phishingListNameKeyMap[phishingList.name],
|
|
592
|
+
[],
|
|
593
|
+
[]
|
|
594
|
+
);
|
|
595
|
+
return updatedList;
|
|
596
|
+
});
|
|
597
|
+
this.update((draftState) => {
|
|
598
|
+
draftState.phishingLists = newPhishingLists;
|
|
599
|
+
});
|
|
600
|
+
this.updatePhishingDetector();
|
|
601
|
+
};
|
|
602
|
+
_updateC2DomainBlocklist = new WeakSet();
|
|
603
|
+
updateC2DomainBlocklist_fn = async function() {
|
|
604
|
+
let c2DomainBlocklistResponse = null;
|
|
605
|
+
try {
|
|
606
|
+
c2DomainBlocklistResponse = await __privateMethod(this, _queryConfig, queryConfig_fn).call(this, `${C2_DOMAIN_BLOCKLIST_URL}?timestamp=${roundToNearestMinute(
|
|
607
|
+
this.state.c2DomainBlocklistLastFetched
|
|
608
|
+
)}`);
|
|
609
|
+
} finally {
|
|
610
|
+
this.update((draftState) => {
|
|
611
|
+
draftState.c2DomainBlocklistLastFetched = fetchTimeNow();
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
if (!c2DomainBlocklistResponse) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
const recentlyAddedC2Domains = c2DomainBlocklistResponse.recentlyAdded;
|
|
618
|
+
const recentlyRemovedC2Domains = c2DomainBlocklistResponse.recentlyRemoved;
|
|
619
|
+
const newPhishingLists = this.state.phishingLists.map((phishingList) => {
|
|
620
|
+
const updatedList = applyDiffs(
|
|
621
|
+
phishingList,
|
|
622
|
+
[],
|
|
623
|
+
phishingListNameKeyMap[phishingList.name],
|
|
624
|
+
recentlyAddedC2Domains,
|
|
625
|
+
recentlyRemovedC2Domains
|
|
626
|
+
);
|
|
627
|
+
return updatedList;
|
|
628
|
+
});
|
|
449
629
|
this.update((draftState) => {
|
|
450
630
|
draftState.phishingLists = newPhishingLists;
|
|
451
631
|
});
|
|
@@ -471,6 +651,9 @@ var PhishingController_default = PhishingController;
|
|
|
471
651
|
// src/utils.ts
|
|
472
652
|
var DEFAULT_TOLERANCE = 3;
|
|
473
653
|
var fetchTimeNow = () => Math.round(Date.now() / 1e3);
|
|
654
|
+
function roundToNearestMinute(unixTimestamp) {
|
|
655
|
+
return Math.floor(unixTimestamp / 60) * 60;
|
|
656
|
+
}
|
|
474
657
|
var splitStringByPeriod = (stringToSplit) => {
|
|
475
658
|
const periodIndex = stringToSplit.indexOf(".");
|
|
476
659
|
return [
|
|
@@ -478,7 +661,7 @@ var splitStringByPeriod = (stringToSplit) => {
|
|
|
478
661
|
stringToSplit.slice(periodIndex + 1)
|
|
479
662
|
];
|
|
480
663
|
};
|
|
481
|
-
var applyDiffs = (listState, hotlistDiffs, listKey) => {
|
|
664
|
+
var applyDiffs = (listState, hotlistDiffs, listKey, recentlyAddedC2Domains = [], recentlyRemovedC2Domains = []) => {
|
|
482
665
|
const diffsToApply = hotlistDiffs.filter(
|
|
483
666
|
({ timestamp, targetList }) => timestamp > listState.lastUpdated && splitStringByPeriod(targetList)[0] === listKey
|
|
484
667
|
);
|
|
@@ -486,7 +669,8 @@ var applyDiffs = (listState, hotlistDiffs, listKey) => {
|
|
|
486
669
|
const listSets = {
|
|
487
670
|
allowlist: new Set(listState.allowlist),
|
|
488
671
|
blocklist: new Set(listState.blocklist),
|
|
489
|
-
fuzzylist: new Set(listState.fuzzylist)
|
|
672
|
+
fuzzylist: new Set(listState.fuzzylist),
|
|
673
|
+
c2DomainBlocklist: new Set(listState.c2DomainBlocklist)
|
|
490
674
|
};
|
|
491
675
|
for (const { isRemoval, targetList, url, timestamp } of diffsToApply) {
|
|
492
676
|
const targetListType = splitStringByPeriod(targetList)[1];
|
|
@@ -499,7 +683,16 @@ var applyDiffs = (listState, hotlistDiffs, listKey) => {
|
|
|
499
683
|
listSets[targetListType].add(url);
|
|
500
684
|
}
|
|
501
685
|
}
|
|
686
|
+
if (listKey === "eth_phishing_detect_config" /* EthPhishingDetectConfig */) {
|
|
687
|
+
for (const hash of recentlyAddedC2Domains) {
|
|
688
|
+
listSets.c2DomainBlocklist.add(hash);
|
|
689
|
+
}
|
|
690
|
+
for (const hash of recentlyRemovedC2Domains) {
|
|
691
|
+
listSets.c2DomainBlocklist.delete(hash);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
502
694
|
return {
|
|
695
|
+
c2DomainBlocklist: Array.from(listSets.c2DomainBlocklist),
|
|
503
696
|
allowlist: Array.from(listSets.allowlist),
|
|
504
697
|
blocklist: Array.from(listSets.blocklist),
|
|
505
698
|
fuzzylist: Array.from(listSets.fuzzylist),
|
|
@@ -564,9 +757,14 @@ var matchPartsAgainstList = (source, list) => {
|
|
|
564
757
|
return target.every((part, index) => source[index] === part);
|
|
565
758
|
});
|
|
566
759
|
};
|
|
760
|
+
var sha256Hash = (hostname) => {
|
|
761
|
+
const hashBuffer = sha256(new TextEncoder().encode(hostname.toLowerCase()));
|
|
762
|
+
return bytesToHex(hashBuffer);
|
|
763
|
+
};
|
|
567
764
|
|
|
568
765
|
export {
|
|
569
766
|
fetchTimeNow,
|
|
767
|
+
roundToNearestMinute,
|
|
570
768
|
applyDiffs,
|
|
571
769
|
validateConfig,
|
|
572
770
|
domainToParts,
|
|
@@ -576,18 +774,23 @@ export {
|
|
|
576
774
|
domainPartsToDomain,
|
|
577
775
|
domainPartsToFuzzyForm,
|
|
578
776
|
matchPartsAgainstList,
|
|
777
|
+
sha256Hash,
|
|
579
778
|
PhishingDetector,
|
|
580
779
|
PHISHING_CONFIG_BASE_URL,
|
|
581
780
|
METAMASK_STALELIST_FILE,
|
|
582
781
|
METAMASK_HOTLIST_DIFF_FILE,
|
|
782
|
+
CLIENT_SIDE_DETECION_BASE_URL,
|
|
783
|
+
C2_DOMAIN_BLOCKLIST_ENDPOINT,
|
|
784
|
+
C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL,
|
|
583
785
|
HOTLIST_REFRESH_INTERVAL,
|
|
584
786
|
STALELIST_REFRESH_INTERVAL,
|
|
585
787
|
METAMASK_STALELIST_URL,
|
|
586
788
|
METAMASK_HOTLIST_DIFF_URL,
|
|
789
|
+
C2_DOMAIN_BLOCKLIST_URL,
|
|
587
790
|
ListKeys,
|
|
588
791
|
ListNames,
|
|
589
792
|
phishingListKeyNameMap,
|
|
590
793
|
PhishingController,
|
|
591
794
|
PhishingController_default
|
|
592
795
|
};
|
|
593
|
-
//# sourceMappingURL=chunk-
|
|
796
|
+
//# sourceMappingURL=chunk-F7CZ3O4X.mjs.map
|